部分修复

This commit is contained in:
2025-09-04 13:38:14 +08:00
parent cca1a969c5
commit eb13979d4d
137 changed files with 6848 additions and 26965 deletions

View File

@@ -1,190 +0,0 @@
/* 背景样式文件 */
/* 主体背景 */
body {
background: linear-gradient(135deg, #e8f5e8 0%, #c8e6c9 50%, #a5d6a7 100%);
background-attachment: fixed;
background-size: 400% 400%;
animation: gradientShift 15s ease infinite;
}
/* 背景动画 */
@keyframes gradientShift {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
/* 装饰性背景元素 */
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image:
radial-gradient(circle at 20% 80%, rgba(76, 175, 80, 0.1) 0%, transparent 50%),
radial-gradient(circle at 80% 20%, rgba(129, 199, 132, 0.1) 0%, transparent 50%),
radial-gradient(circle at 40% 40%, rgba(165, 214, 167, 0.08) 0%, transparent 50%);
pointer-events: none;
z-index: -1;
}
/* 浮动装饰圆点 */
body::after {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image:
radial-gradient(2px 2px at 20px 30px, rgba(76, 175, 80, 0.3), transparent),
radial-gradient(2px 2px at 40px 70px, rgba(129, 199, 132, 0.2), transparent),
radial-gradient(1px 1px at 90px 40px, rgba(165, 214, 167, 0.3), transparent),
radial-gradient(1px 1px at 130px 80px, rgba(76, 175, 80, 0.2), transparent),
radial-gradient(2px 2px at 160px 30px, rgba(129, 199, 132, 0.3), transparent);
background-repeat: repeat;
background-size: 200px 100px;
animation: float 20s linear infinite;
pointer-events: none;
z-index: -1;
opacity: 0.6;
}
@keyframes float {
0% {
transform: translateY(0px);
}
50% {
transform: translateY(-10px);
}
100% {
transform: translateY(0px);
}
}
/* 题目容器背景增强 */
.question-container {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2);
box-shadow:
0 8px 32px rgba(26, 77, 26, 0.1),
inset 0 1px 0 rgba(255, 255, 255, 0.2);
}
/* 错误容器背景 */
.error-container {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
}
/* 结果容器背景 */
.result-container {
background: rgba(255, 255, 255, 0.9);
backdrop-filter: blur(5px);
-webkit-backdrop-filter: blur(5px);
}
/* 代码块背景 */
.code-block {
background: rgba(248, 249, 250, 0.9);
backdrop-filter: blur(5px);
-webkit-backdrop-filter: blur(5px);
}
/* 选项背景 */
.option {
background: rgba(255, 255, 255, 0.8);
backdrop-filter: blur(5px);
-webkit-backdrop-filter: blur(5px);
}
.option:hover {
background: rgba(76, 175, 80, 0.05);
}
.option.selected {
background: linear-gradient(135deg, rgba(76, 175, 80, 0.15), rgba(76, 175, 80, 0.08));
}
/* 按钮背景增强 */
.submit-btn {
background: linear-gradient(135deg, #4caf50, #45a049);
box-shadow: 0 4px 15px rgba(76, 175, 80, 0.2);
}
.show-answer-btn {
background: linear-gradient(135deg, #2196f3, #1976d2);
box-shadow: 0 4px 15px rgba(33, 150, 243, 0.2);
}
.retry-btn {
background: linear-gradient(135deg, #ff9800, #f57c00);
box-shadow: 0 4px 15px rgba(255, 152, 0, 0.2);
}
.refresh-btn {
background: linear-gradient(135deg, #4caf50, #45a049);
box-shadow: 0 4px 15px rgba(76, 175, 80, 0.2);
}
/* 移动端背景优化 */
@media (max-width: 768px) {
body {
background-attachment: scroll;
}
body::after {
opacity: 0.4;
background-size: 150px 75px;
}
.question-container {
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
}
}
/* 高对比度模式支持 */
@media (prefers-contrast: high) {
body {
background: #f0f8f0;
}
body::before,
body::after {
display: none;
}
.question-container {
background: #ffffff;
border: 2px solid #4caf50;
}
}
/* 减少动画模式支持 */
@media (prefers-reduced-motion: reduce) {
body {
animation: none;
background: #e8f5e8;
}
body::after {
animation: none;
}
.refresh-btn:hover {
transform: scale(1.1);
}
}

View File

@@ -1,597 +0,0 @@
/* 基础样式重置 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif;
line-height: 1.6;
color: #2d5a27;
min-height: 100vh;
overflow-x: hidden;
}
/* 容器布局 */
.container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
min-height: 100vh;
display: flex;
flex-direction: column;
}
/* 头部样式 */
.header {
text-align: center;
margin-bottom: 40px;
padding: 30px 0;
}
.header h1 {
font-size: 2.5rem;
color: #1a4d1a;
margin-bottom: 10px;
font-weight: 700;
text-shadow: 0 2px 4px rgba(26, 77, 26, 0.1);
}
.subtitle {
font-size: 1.1rem;
color: #4a7c59;
opacity: 0.8;
}
/* 主内容区域 */
.main-content {
flex: 1;
display: flex;
justify-content: center;
align-items: flex-start;
}
/* 加载动画 */
.loading {
text-align: center;
padding: 60px 20px;
}
.spinner {
width: 50px;
height: 50px;
border: 4px solid #e8f5e8;
border-top: 4px solid #4caf50;
border-radius: 50%;
animation: spin 1s linear infinite;
margin: 0 auto 20px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.loading p {
color: #4a7c59;
font-size: 1.1rem;
}
/* 题目容器 */
.question-container {
background: rgba(255, 255, 255, 0.95);
border-radius: 20px;
padding: 40px;
box-shadow: 0 10px 30px rgba(26, 77, 26, 0.1);
border: 2px solid rgba(76, 175, 80, 0.2);
width: 100%;
max-width: 800px;
backdrop-filter: blur(10px);
}
/* 题目头部 */
.question-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30px;
padding-bottom: 15px;
border-bottom: 2px solid #e8f5e8;
}
.question-id {
font-size: 1.1rem;
color: #4caf50;
font-weight: 600;
background: linear-gradient(135deg, #e8f5e8, #c8e6c9);
padding: 8px 16px;
border-radius: 20px;
}
.refresh-btn {
background: linear-gradient(135deg, #4caf50, #45a049);
border: none;
border-radius: 50%;
width: 45px;
height: 45px;
color: white;
cursor: pointer;
transition: all 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
}
.refresh-btn:hover {
transform: rotate(180deg) scale(1.1);
box-shadow: 0 5px 15px rgba(76, 175, 80, 0.3);
}
/* 题目文本 */
.question-text h2 {
font-size: 1.5rem;
color: #1a4d1a;
margin-bottom: 25px;
text-align: center;
}
/* 代码块 */
.code-block {
background: #f8f9fa;
border: 2px solid #e8f5e8;
border-radius: 12px;
margin: 25px 0;
overflow-x: auto;
position: relative;
}
.code-block pre {
margin: 0;
padding: 25px;
font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
font-size: 0.95rem;
line-height: 1.5;
color: #2d5a27;
white-space: pre-wrap;
word-wrap: break-word;
background: transparent !important;
}
.code-block code {
font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
background: transparent !important;
}
/* 代码高亮自定义样式 - 丰富的语法高亮 */
.code-block .hljs {
background: transparent !important;
color: #333333 !important;
}
/* JavaScript 关键字 - 蓝色 */
.code-block .hljs-keyword {
color: #0066cc !important;
font-weight: 600;
}
/* 字符串 - 绿色 */
.code-block .hljs-string {
color: #22aa22 !important;
}
/* 数字 - 橙色 */
.code-block .hljs-number {
color: #ff6600 !important;
}
/* 函数名 - 紫色 */
.code-block .hljs-function,
.code-block .hljs-title.function_ {
color: #9933cc !important;
font-weight: 600;
}
/* 变量名 - 深蓝色 */
.code-block .hljs-variable,
.code-block .hljs-name {
color: #0066aa !important;
}
/* 注释 - 灰色 */
.code-block .hljs-comment {
color: #888888 !important;
font-style: italic;
}
/* 内置对象和方法 - 深紫色 */
.code-block .hljs-built_in {
color: #663399 !important;
font-weight: 500;
}
/* 字面量 (true, false, null) - 红色 */
.code-block .hljs-literal {
color: #cc0000 !important;
font-weight: 600;
}
/* 操作符 - 深灰色 */
.code-block .hljs-operator {
color: #666666 !important;
}
/* 标点符号 - 深灰色 */
.code-block .hljs-punctuation {
color: #666666 !important;
}
/* 属性名 - 深蓝色 */
.code-block .hljs-property,
.code-block .hljs-attr {
color: #0066aa !important;
}
/* 类名和构造函数 - 深绿色 */
.code-block .hljs-title.class_,
.code-block .hljs-title {
color: #228833 !important;
font-weight: 600;
}
/* 参数 - 深蓝色 */
.code-block .hljs-params {
color: #0066aa !important;
}
/* 正则表达式 - 深红色 */
.code-block .hljs-regexp {
color: #aa0066 !important;
}
/* 模板字符串 - 深绿色 */
.code-block .hljs-template-variable,
.code-block .hljs-template-tag {
color: #228833 !important;
}
/* 选项容器 */
.options-container {
margin: 30px 0;
}
.option {
background: rgba(255, 255, 255, 0.8);
border: 2px solid #e8f5e8;
border-radius: 12px;
padding: 15px 20px;
margin: 12px 0;
cursor: pointer;
transition: all 0.3s ease;
font-size: 1rem;
position: relative;
overflow: hidden;
}
.option:hover {
border-color: #4caf50;
background: rgba(76, 175, 80, 0.05);
transform: translateX(5px);
}
.option.selected {
border-color: #4caf50;
background: linear-gradient(135deg, rgba(76, 175, 80, 0.1), rgba(76, 175, 80, 0.05));
color: #1a4d1a;
font-weight: 600;
}
.option.correct {
border-color: #4caf50;
background: linear-gradient(135deg, rgba(76, 175, 80, 0.2), rgba(76, 175, 80, 0.1));
color: #1a4d1a;
}
.option.incorrect {
border-color: #f44336;
background: linear-gradient(135deg, rgba(244, 67, 54, 0.1), rgba(244, 67, 54, 0.05));
color: #c62828;
}
/* 按钮样式 */
.action-buttons {
display: flex;
gap: 15px;
margin: 30px 0;
justify-content: center;
flex-wrap: wrap;
}
.submit-btn, .show-answer-btn, .retry-btn, .export-btn {
padding: 12px 30px;
border: none;
border-radius: 25px;
font-size: 1rem;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
min-width: 120px;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
}
.submit-btn {
background: linear-gradient(135deg, #4caf50, #45a049);
color: white;
}
.submit-btn:hover:not(:disabled) {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(76, 175, 80, 0.3);
}
.submit-btn:disabled {
background: #cccccc;
cursor: not-allowed;
transform: none;
box-shadow: none;
}
.show-answer-btn {
background: linear-gradient(135deg, #2196f3, #1976d2);
color: white;
}
.show-answer-btn:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(33, 150, 243, 0.3);
}
.retry-btn {
background: linear-gradient(135deg, #ff9800, #f57c00);
color: white;
}
.retry-btn:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(255, 152, 0, 0.3);
}
.export-btn {
background: linear-gradient(135deg, #9c27b0, #7b1fa2);
color: white;
}
.export-btn:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(156, 39, 176, 0.3);
}
.export-btn svg {
width: 16px;
height: 16px;
}
/* 结果容器 */
.result-container {
margin-top: 30px;
padding: 25px;
background: rgba(255, 255, 255, 0.9);
border-radius: 15px;
border: 2px solid #e8f5e8;
}
.result-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 1px solid #e8f5e8;
}
.result-status {
font-size: 1.2rem;
font-weight: 600;
}
.result-status.correct {
color: #4caf50;
}
.result-status.incorrect {
color: #f44336;
}
.correct-answer {
font-weight: 600;
color: #4caf50;
background: rgba(76, 175, 80, 0.1);
padding: 5px 12px;
border-radius: 15px;
}
.explanation {
color: #2d5a27;
line-height: 1.7;
font-size: 1rem;
}
.explanation pre {
background: #f8f9fa;
border: 1px solid #e8f5e8;
border-radius: 8px;
padding: 15px;
margin: 15px 0;
overflow-x: auto;
font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
}
/* 错误容器 */
.error-container {
text-align: center;
padding: 60px 20px;
background: rgba(255, 255, 255, 0.9);
border-radius: 20px;
border: 2px solid rgba(244, 67, 54, 0.2);
max-width: 500px;
margin: 0 auto;
}
.error-icon {
font-size: 3rem;
margin-bottom: 20px;
}
.error-container h3 {
color: #f44336;
margin-bottom: 15px;
font-size: 1.5rem;
}
.error-container p {
color: #666;
margin-bottom: 25px;
font-size: 1.1rem;
}
/* 底部 */
.footer {
text-align: center;
padding: 30px 0;
margin-top: 40px;
color: #4a7c59;
opacity: 0.7;
border-top: 1px solid rgba(76, 175, 80, 0.2);
}
/* 平板端适配 (768px - 1024px) */
@media (max-width: 1024px) and (min-width: 768px) {
.container {
padding: 15px;
}
.header h1 {
font-size: 2.2rem;
}
.question-container {
padding: 30px;
}
.action-buttons {
flex-wrap: wrap;
}
}
/* 手机端适配 (最大768px) */
@media (max-width: 768px) {
.container {
padding: 10px;
}
.header {
margin-bottom: 25px;
padding: 20px 0;
}
.header h1 {
font-size: 1.8rem;
}
.subtitle {
font-size: 1rem;
}
.question-container {
padding: 20px;
border-radius: 15px;
}
.question-header {
flex-direction: column;
gap: 15px;
text-align: center;
}
.question-text h2 {
font-size: 1.3rem;
}
.code-block pre {
padding: 15px;
font-size: 0.85rem;
}
.option {
padding: 12px 15px;
font-size: 0.95rem;
}
.action-buttons {
flex-direction: column;
align-items: center;
}
.submit-btn, .show-answer-btn, .retry-btn {
width: 100%;
max-width: 200px;
}
.result-header {
flex-direction: column;
gap: 10px;
text-align: center;
}
.explanation {
font-size: 0.95rem;
}
.explanation pre {
padding: 10px;
font-size: 0.8rem;
}
}
/* 小屏手机适配 (最大480px) */
@media (max-width: 480px) {
.container {
padding: 8px;
}
.header h1 {
font-size: 1.6rem;
}
.question-container {
padding: 15px;
}
.question-id {
font-size: 1rem;
padding: 6px 12px;
}
.refresh-btn {
width: 40px;
height: 40px;
}
.code-block pre {
font-size: 0.8rem;
padding: 12px;
}
.option {
padding: 10px 12px;
font-size: 0.9rem;
}
.submit-btn, .show-answer-btn, .retry-btn {
padding: 10px 20px;
font-size: 0.95rem;
}
}

View File

@@ -1,89 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>随机JavaScript趣味题</title>
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="css/background.css">
<link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/highlight.js/11.9.0/styles/github.min.css">
<script src="https://cdn.bootcdn.net/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/highlight.js/11.9.0/languages/javascript.min.js"></script>
</head>
<body>
<div class="container">
<header class="header">
<h1>JavaScript趣味题</h1>
<p class="subtitle">测试你的JavaScript知识</p>
</header>
<main class="main-content">
<div class="loading" id="loading">
<div class="spinner"></div>
<p>正在加载题目...</p>
</div>
<div class="question-container" id="questionContainer" style="display: none;">
<div class="question-header">
<span class="question-id" id="questionId">题目 #1</span>
<button class="refresh-btn" id="refreshBtn" title="获取新题目">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<polyline points="23 4 23 10 17 10"></polyline>
<polyline points="1 20 1 14 7 14"></polyline>
<path d="M20.49 9A9 9 0 0 0 5.64 5.64L1 10m22 4l-4.64 4.36A9 9 0 0 1 3.51 15"></path>
</svg>
</button>
</div>
<div class="question-text" id="questionText">
<h2>输出是什么?</h2>
</div>
<div class="code-block" id="codeBlock">
<pre><code id="codeContent" class="language-javascript"></code></pre>
</div>
<div class="options-container" id="optionsContainer">
<!-- 选项将通过JavaScript动态生成 -->
</div>
<div class="action-buttons">
<button class="submit-btn" id="submitBtn" disabled>提交答案</button>
<button class="show-answer-btn" id="showAnswerBtn">查看答案</button>
<button class="export-btn" id="exportBtn" title="导出为Markdown文件">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
<polyline points="7 10 12 15 17 10"></polyline>
<line x1="12" y1="15" x2="12" y2="3"></line>
</svg>
导出MD
</button>
</div>
<div class="result-container" id="resultContainer" style="display: none;">
<div class="result-header">
<span class="result-status" id="resultStatus"></span>
<span class="correct-answer" id="correctAnswer"></span>
</div>
<div class="explanation" id="explanation">
<!-- 解析内容 -->
</div>
</div>
</div>
<div class="error-container" id="errorContainer" style="display: none;">
<div class="error-icon">⚠️</div>
<h3>加载失败</h3>
<p id="errorMessage">网络连接异常,请稍后重试</p>
<button class="retry-btn" id="retryBtn">重新加载</button>
</div>
</main>
<footer class="footer">
<p>JavaScript趣味题集合</p>
</footer>
</div>
<script src="js/script.js"></script>
</body>
</html>

View File

@@ -1,565 +0,0 @@
// JavaScript趣味题应用
class JSQuizApp {
constructor() {
this.apiEndpoints = [
'https://60s-cf.viki.moe',
'https://60s.viki.moe',
'https://60s.b23.run',
'https://60s.114128.xyz',
'https://60s-cf.114128.xyz'
];
this.currentApiIndex = 0;
this.currentQuestion = null;
this.selectedOption = null;
this.isAnswered = false;
this.initElements();
this.bindEvents();
this.loadQuestion();
}
// 初始化DOM元素
initElements() {
this.elements = {
loading: document.getElementById('loading'),
questionContainer: document.getElementById('questionContainer'),
errorContainer: document.getElementById('errorContainer'),
questionId: document.getElementById('questionId'),
questionText: document.getElementById('questionText'),
codeContent: document.getElementById('codeContent'),
optionsContainer: document.getElementById('optionsContainer'),
submitBtn: document.getElementById('submitBtn'),
showAnswerBtn: document.getElementById('showAnswerBtn'),
refreshBtn: document.getElementById('refreshBtn'),
retryBtn: document.getElementById('retryBtn'),
exportBtn: document.getElementById('exportBtn'),
resultContainer: document.getElementById('resultContainer'),
resultStatus: document.getElementById('resultStatus'),
correctAnswer: document.getElementById('correctAnswer'),
explanation: document.getElementById('explanation'),
errorMessage: document.getElementById('errorMessage')
};
}
// 绑定事件
bindEvents() {
this.elements.submitBtn.addEventListener('click', () => this.submitAnswer());
this.elements.showAnswerBtn.addEventListener('click', () => this.showAnswer());
this.elements.refreshBtn.addEventListener('click', () => this.loadQuestion());
this.elements.retryBtn.addEventListener('click', () => this.loadQuestion());
this.elements.exportBtn.addEventListener('click', () => this.exportToMarkdown());
}
// 显示加载状态
showLoading() {
this.elements.loading.style.display = 'block';
this.elements.questionContainer.style.display = 'none';
this.elements.errorContainer.style.display = 'none';
}
// 显示题目
showQuestion() {
this.elements.loading.style.display = 'none';
this.elements.questionContainer.style.display = 'block';
this.elements.errorContainer.style.display = 'none';
}
// 显示错误
showError(message) {
this.elements.loading.style.display = 'none';
this.elements.questionContainer.style.display = 'none';
this.elements.errorContainer.style.display = 'block';
this.elements.errorMessage.textContent = message;
}
// 获取当前API地址
getCurrentApiUrl() {
return `${this.apiEndpoints[this.currentApiIndex]}/v2/awesome-js`;
}
// 切换到下一个API
switchToNextApi() {
this.currentApiIndex = (this.currentApiIndex + 1) % this.apiEndpoints.length;
}
// 加载题目
async loadQuestion() {
this.showLoading();
this.resetQuestion();
let attempts = 0;
const maxAttempts = this.apiEndpoints.length;
while (attempts < maxAttempts) {
try {
const response = await fetch(this.getCurrentApiUrl(), {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
timeout: 10000
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const data = await response.json();
if (data.code === 200 && data.data) {
this.currentQuestion = data.data;
this.displayQuestion();
return;
} else {
throw new Error(data.message || '数据格式错误');
}
} catch (error) {
console.warn(`API ${this.getCurrentApiUrl()} 请求失败:`, error.message);
attempts++;
if (attempts < maxAttempts) {
this.switchToNextApi();
console.log(`切换到备用API: ${this.getCurrentApiUrl()}`);
} else {
this.showError(`所有API接口都无法访问请检查网络连接后重试。\n最后尝试的错误: ${error.message}`);
return;
}
}
}
}
// 重置题目状态
resetQuestion() {
this.selectedOption = null;
this.isAnswered = false;
this.elements.resultContainer.style.display = 'none';
this.elements.submitBtn.disabled = true;
this.elements.submitBtn.textContent = '提交答案';
this.elements.showAnswerBtn.style.display = 'inline-block';
// 清空选项容器,防止重复显示
this.elements.optionsContainer.innerHTML = '';
// 移除所有选项的事件监听器
const existingOptions = document.querySelectorAll('.option');
existingOptions.forEach(option => {
option.removeEventListener('click', this.selectOption);
});
}
// 显示题目内容
displayQuestion() {
const question = this.currentQuestion;
console.log('显示题目:', question);
// 设置题目ID
this.elements.questionId.textContent = `题目 #${question.id}`;
// 设置题目文本
this.elements.questionText.innerHTML = `<h2>${this.escapeHtml(question.question)}</h2>`;
// 设置代码内容并应用语法高亮
this.elements.codeContent.textContent = question.code;
// 应用语法高亮
if (typeof hljs !== 'undefined') {
hljs.highlightElement(this.elements.codeContent);
}
// 确保选项容器已清空
this.elements.optionsContainer.innerHTML = '';
// 生成选项
this.generateOptions(question.options);
this.showQuestion();
}
// 生成选项
generateOptions(options) {
// 确保清空容器
this.elements.optionsContainer.innerHTML = '';
// 验证选项数据
if (!Array.isArray(options) || options.length === 0) {
console.error('选项数据无效:', options);
return;
}
// 移除可能存在的重复选项
const uniqueOptions = [...new Set(options)];
uniqueOptions.forEach((option, index) => {
const optionElement = document.createElement('div');
optionElement.className = 'option';
optionElement.textContent = option;
optionElement.dataset.index = index;
optionElement.dataset.value = option.charAt(0); // A, B, C, D
optionElement.addEventListener('click', () => this.selectOption(optionElement));
this.elements.optionsContainer.appendChild(optionElement);
});
console.log('生成选项:', uniqueOptions);
}
// 选择选项
selectOption(optionElement) {
if (this.isAnswered) return;
// 移除之前的选中状态
document.querySelectorAll('.option.selected').forEach(el => {
el.classList.remove('selected');
});
// 设置当前选中
optionElement.classList.add('selected');
this.selectedOption = optionElement.dataset.value;
// 启用提交按钮
this.elements.submitBtn.disabled = false;
}
// 提交答案
submitAnswer() {
if (!this.selectedOption || this.isAnswered) return;
this.isAnswered = true;
this.elements.submitBtn.disabled = true;
this.elements.submitBtn.textContent = '已提交';
this.elements.showAnswerBtn.style.display = 'none';
const isCorrect = this.selectedOption === this.currentQuestion.answer;
// 显示结果
this.showResult(isCorrect);
// 标记选项
this.markOptions();
}
// 显示答案
showAnswer() {
this.isAnswered = true;
this.elements.submitBtn.disabled = true;
this.elements.submitBtn.textContent = '已显示答案';
this.elements.showAnswerBtn.style.display = 'none';
// 显示结果(不判断对错)
this.showResult(null);
// 标记正确答案
this.markCorrectAnswer();
}
// 显示结果
showResult(isCorrect) {
const resultContainer = this.elements.resultContainer;
const resultStatus = this.elements.resultStatus;
const correctAnswer = this.elements.correctAnswer;
const explanation = this.elements.explanation;
// 设置结果状态
if (isCorrect === true) {
resultStatus.textContent = '✅ 回答正确!';
resultStatus.className = 'result-status correct';
} else if (isCorrect === false) {
resultStatus.textContent = '❌ 回答错误';
resultStatus.className = 'result-status incorrect';
} else {
resultStatus.textContent = '💡 答案解析';
resultStatus.className = 'result-status';
}
// 设置正确答案
correctAnswer.textContent = `正确答案: ${this.currentQuestion.answer}`;
// 设置解析内容
explanation.innerHTML = this.formatExplanation(this.currentQuestion.explanation);
// 显示结果容器
resultContainer.style.display = 'block';
// 滚动到结果区域
setTimeout(() => {
resultContainer.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
}, 100);
}
// 标记选项
markOptions() {
const options = document.querySelectorAll('.option');
const correctAnswer = this.currentQuestion.answer;
options.forEach(option => {
const optionValue = option.dataset.value;
if (optionValue === correctAnswer) {
option.classList.add('correct');
} else if (option.classList.contains('selected')) {
option.classList.add('incorrect');
}
// 禁用点击
option.style.pointerEvents = 'none';
});
}
// 标记正确答案
markCorrectAnswer() {
const options = document.querySelectorAll('.option');
const correctAnswer = this.currentQuestion.answer;
options.forEach(option => {
const optionValue = option.dataset.value;
if (optionValue === correctAnswer) {
option.classList.add('correct');
}
// 禁用点击
option.style.pointerEvents = 'none';
});
}
// 格式化解析内容
formatExplanation(explanation) {
// 转义HTML
let formatted = this.escapeHtml(explanation);
// 处理代码块
formatted = formatted.replace(/```js\n([\s\S]*?)\n```/g, '<pre><code>$1</code></pre>');
formatted = formatted.replace(/```javascript\n([\s\S]*?)\n```/g, '<pre><code>$1</code></pre>');
formatted = formatted.replace(/```([\s\S]*?)```/g, '<pre><code>$1</code></pre>');
// 处理行内代码
formatted = formatted.replace(/`([^`]+)`/g, '<code style="background: #f0f0f0; padding: 2px 4px; border-radius: 3px; font-family: monospace;">$1</code>');
// 处理换行
formatted = formatted.replace(/\n\n/g, '</p><p>');
formatted = formatted.replace(/\n/g, '<br>');
// 包装段落
if (!formatted.includes('<p>')) {
formatted = '<p>' + formatted + '</p>';
}
return formatted;
}
// HTML转义
escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
// 导出为Markdown
exportToMarkdown() {
if (!this.currentQuestion) {
alert('请先加载题目后再导出!');
return;
}
const question = this.currentQuestion;
const timestamp = new Date().toLocaleString('zh-CN');
// 构建Markdown内容
let markdown = `# JavaScript趣味题 #${question.id}\n\n`;
markdown += `> 导出时间: ${timestamp}\n\n`;
// 题目部分
markdown += `## 题目\n\n`;
markdown += `${question.question}\n\n`;
// 代码部分
markdown += `## 代码\n\n`;
markdown += `\`\`\`javascript\n${question.code}\n\`\`\`\n\n`;
// 选项部分
markdown += `## 选项\n\n`;
question.options.forEach((option, index) => {
const letter = String.fromCharCode(65 + index); // A, B, C, D
const isCorrect = letter === question.answer;
markdown += `${letter}. ${option}${isCorrect ? ' ✅' : ''}\n`;
});
markdown += `\n`;
// 答案部分
markdown += `## 正确答案\n\n`;
markdown += `**${question.answer}**\n\n`;
// 解析部分
markdown += `## 答案解析\n\n`;
// 清理解析内容中的HTML标签转换为Markdown格式
let explanation = question.explanation;
explanation = explanation.replace(/<br\s*\/?>/gi, '\n');
explanation = explanation.replace(/<p>/gi, '\n');
explanation = explanation.replace(/<\/p>/gi, '\n');
explanation = explanation.replace(/<code[^>]*>/gi, '`');
explanation = explanation.replace(/<\/code>/gi, '`');
explanation = explanation.replace(/<pre><code>/gi, '\n```javascript\n');
explanation = explanation.replace(/<\/code><\/pre>/gi, '\n```\n');
explanation = explanation.replace(/<[^>]*>/g, ''); // 移除其他HTML标签
explanation = explanation.replace(/\n\s*\n/g, '\n\n'); // 清理多余空行
markdown += explanation.trim() + '\n\n';
// 添加页脚
markdown += `---\n\n`;
markdown += `*本题目来源于JavaScript趣味题集合*\n`;
markdown += `*导出工具: JavaScript趣味题网页版*\n`;
// 创建下载
this.downloadMarkdown(markdown, `JavaScript趣味题_${question.id}_${new Date().getTime()}.md`);
}
// 下载Markdown文件
downloadMarkdown(content, filename) {
const blob = new Blob([content], { type: 'text/markdown;charset=utf-8' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = filename;
link.style.display = 'none';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
// 清理URL对象
setTimeout(() => {
URL.revokeObjectURL(url);
}, 100);
// 显示成功提示
this.showExportSuccess(filename);
}
// 显示导出成功提示
showExportSuccess(filename) {
// 创建临时提示元素
const toast = document.createElement('div');
toast.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
background: linear-gradient(135deg, #4caf50, #45a049);
color: white;
padding: 15px 20px;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(76, 175, 80, 0.3);
z-index: 10000;
font-size: 14px;
max-width: 300px;
word-wrap: break-word;
animation: slideInRight 0.3s ease-out;
`;
toast.innerHTML = `
<div style="display: flex; align-items: center; gap: 8px;">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<polyline points="20 6 9 17 4 12"></polyline>
</svg>
<div>
<div style="font-weight: 600;">导出成功!</div>
<div style="font-size: 12px; opacity: 0.9; margin-top: 2px;">${filename}</div>
</div>
</div>
`;
// 添加动画样式
const style = document.createElement('style');
style.textContent = `
@keyframes slideInRight {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
@keyframes slideOutRight {
from {
transform: translateX(0);
opacity: 1;
}
to {
transform: translateX(100%);
opacity: 0;
}
}
`;
document.head.appendChild(style);
document.body.appendChild(toast);
// 3秒后自动消失
setTimeout(() => {
toast.style.animation = 'slideOutRight 0.3s ease-in';
setTimeout(() => {
if (toast.parentNode) {
document.body.removeChild(toast);
}
if (style.parentNode) {
document.head.removeChild(style);
}
}, 300);
}, 3000);
}
}
// 页面加载完成后初始化应用
document.addEventListener('DOMContentLoaded', () => {
new JSQuizApp();
});
// 添加键盘快捷键支持
document.addEventListener('keydown', (e) => {
// 按R键刷新题目
if (e.key.toLowerCase() === 'r' && !e.ctrlKey && !e.metaKey) {
const refreshBtn = document.getElementById('refreshBtn');
if (refreshBtn && !document.querySelector('.loading').style.display !== 'none') {
refreshBtn.click();
}
}
// 按数字键1-4选择选项
if (['1', '2', '3', '4'].includes(e.key)) {
const options = document.querySelectorAll('.option');
const index = parseInt(e.key) - 1;
if (options[index] && !options[index].style.pointerEvents) {
options[index].click();
}
}
// 按Enter键提交答案
if (e.key === 'Enter') {
const submitBtn = document.getElementById('submitBtn');
if (submitBtn && !submitBtn.disabled) {
submitBtn.click();
}
}
});
// 添加触摸设备支持
if ('ontouchstart' in window) {
document.addEventListener('touchstart', () => {}, { passive: true });
}
// 添加网络状态监听
if ('navigator' in window && 'onLine' in navigator) {
window.addEventListener('online', () => {
console.log('网络连接已恢复');
});
window.addEventListener('offline', () => {
console.log('网络连接已断开');
});
}

View File

@@ -1,7 +0,0 @@
[
"https://60s-cf.viki.moe",
"https://60s.viki.moe",
"https://60s.b23.run",
"https://60s.114128.xyz",
"https://60s-cf.114128.xyz"
]

View File

@@ -1,17 +0,0 @@
{
"code": 200,
"message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s反馈群 595941841",
"data": {
"id": 11,
"question": "输出是什么?",
"code": "function Person(firstName, lastName) {\n this.firstName = firstName;\n this.lastName = lastName;\n}\n\nconst member = new Person(\"Lydia\", \"Hallie\");\nPerson.getFullName = function () {\n return `${this.firstName} ${this.lastName}`;\n}\n\nconsole.log(member.getFullName());",
"options": [
"A: `TypeError`",
"B: `SyntaxError`",
"C: `Lydia Hallie`",
"D: `undefined` `undefined`"
],
"answer": "A",
"explanation": "你不能像常规对象那样,给构造函数添加属性。如果你想一次性给所有实例添加特性,你应该使用原型。因此本例中,使用如下方式:\n\n```js\nPerson.prototype.getFullName = function () {\n return `${this.firstName} ${this.lastName}`;\n}\n```\n\n这才会使 `member.getFullName()` 起作用。为什么这么做有益的?假设我们将这个方法添加到构造函数本身里。也许不是每个 `Person` 实例都需要这个方法。这将浪费大量内存空间,因为它们仍然具有该属性,这将占用每个实例的内存空间。相反,如果我们只将它添加到原型中,那么它只存在于内存中的一个位置,但是所有实例都可以访问它!"
}
}

View File

@@ -1,81 +0,0 @@
/* 背景样式文件 */
body {
background: linear-gradient(135deg, #a8e6cf 0%, #dcedc1 25%, #ffd3a5 50%, #a8e6cf 75%, #88d8a3 100%);
background-size: 400% 400%;
animation: gradientShift 15s ease infinite;
position: relative;
}
/* 背景动画 */
@keyframes gradientShift {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
/* 背景装饰元素 */
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image:
radial-gradient(circle at 20% 80%, rgba(39, 174, 96, 0.1) 0%, transparent 50%),
radial-gradient(circle at 80% 20%, rgba(46, 204, 113, 0.1) 0%, transparent 50%),
radial-gradient(circle at 40% 40%, rgba(26, 188, 156, 0.05) 0%, transparent 50%);
pointer-events: none;
z-index: -1;
}
/* 浮动装饰圆点 */
body::after {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image:
radial-gradient(2px 2px at 20px 30px, rgba(39, 174, 96, 0.3), transparent),
radial-gradient(2px 2px at 40px 70px, rgba(46, 204, 113, 0.2), transparent),
radial-gradient(1px 1px at 90px 40px, rgba(26, 188, 156, 0.3), transparent),
radial-gradient(1px 1px at 130px 80px, rgba(39, 174, 96, 0.2), transparent),
radial-gradient(2px 2px at 160px 30px, rgba(46, 204, 113, 0.3), transparent);
background-repeat: repeat;
background-size: 200px 100px;
animation: floatDots 20s linear infinite;
pointer-events: none;
z-index: -1;
}
@keyframes floatDots {
0% {
transform: translateY(0px);
}
100% {
transform: translateY(-100px);
}
}
/* 响应式背景调整 */
@media (max-width: 768px) {
body::after {
background-size: 150px 75px;
animation-duration: 25s;
}
}
@media (max-width: 480px) {
body::after {
background-size: 100px 50px;
animation-duration: 30s;
}
}

View File

@@ -1,339 +0,0 @@
/* 基础样式重置 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Microsoft YaHei', 'PingFang SC', 'Helvetica Neue', Arial, sans-serif;
line-height: 1.6;
color: #2c3e50;
min-height: 100vh;
overflow-x: hidden;
}
/* 容器布局 */
.container {
min-height: 100vh;
display: flex;
flex-direction: column;
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
/* 头部样式 */
.header {
text-align: center;
margin-bottom: 40px;
padding: 30px 0;
}
.title {
font-size: 2.5rem;
font-weight: 700;
color: #27ae60;
margin-bottom: 10px;
text-shadow: 0 2px 4px rgba(39, 174, 96, 0.2);
}
.subtitle {
font-size: 1.1rem;
color: #7f8c8d;
font-weight: 400;
}
/* 主要内容区域 */
.main {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
}
.content-card {
background: rgba(255, 255, 255, 0.95);
border-radius: 20px;
padding: 40px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
backdrop-filter: blur(10px);
border: 1px solid rgba(39, 174, 96, 0.1);
width: 100%;
max-width: 600px;
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.content-card:hover {
transform: translateY(-5px);
box-shadow: 0 15px 40px rgba(0, 0, 0, 0.15);
}
/* KFC文案内容 */
.kfc-content {
min-height: 200px;
padding: 30px;
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
border-radius: 15px;
border-left: 5px solid #27ae60;
margin-bottom: 30px;
position: relative;
overflow: hidden;
}
.kfc-content::before {
content: '"';
position: absolute;
top: 10px;
left: 15px;
font-size: 3rem;
color: #27ae60;
opacity: 0.3;
font-family: serif;
}
.kfc-content p {
font-size: 1.1rem;
line-height: 1.8;
color: #2c3e50;
margin-left: 20px;
position: relative;
z-index: 1;
}
.loading-text {
text-align: center;
color: #7f8c8d;
font-style: italic;
}
/* 按钮组 */
.button-group {
display: flex;
gap: 15px;
justify-content: center;
margin-bottom: 20px;
}
.generate-btn, .copy-btn {
padding: 15px 30px;
border: none;
border-radius: 50px;
font-size: 1rem;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.generate-btn {
background: linear-gradient(135deg, #27ae60 0%, #2ecc71 100%);
color: white;
box-shadow: 0 4px 15px rgba(39, 174, 96, 0.3);
}
.generate-btn:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(39, 174, 96, 0.4);
}
.generate-btn:active {
transform: translateY(0);
}
.generate-btn:disabled {
opacity: 0.7;
cursor: not-allowed;
transform: none;
}
.copy-btn {
background: linear-gradient(135deg, #3498db 0%, #5dade2 100%);
color: white;
box-shadow: 0 4px 15px rgba(52, 152, 219, 0.3);
}
.copy-btn:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(52, 152, 219, 0.4);
}
/* 编号信息 */
.index-info {
text-align: center;
padding: 10px;
background: rgba(39, 174, 96, 0.1);
border-radius: 10px;
border: 1px solid rgba(39, 174, 96, 0.2);
}
.index-text {
color: #27ae60;
font-weight: 600;
font-size: 0.9rem;
}
#indexNumber {
color: #2c3e50;
font-weight: 700;
}
/* 底部 */
.footer {
text-align: center;
padding: 20px 0;
color: #7f8c8d;
font-size: 0.9rem;
margin-top: 40px;
}
/* 提示框 */
.toast {
position: fixed;
top: 20px;
right: 20px;
background: #27ae60;
color: white;
padding: 15px 25px;
border-radius: 10px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
transform: translateX(400px);
transition: transform 0.3s ease;
z-index: 1000;
font-weight: 600;
}
.toast.show {
transform: translateX(0);
}
/* 平板端适配 (768px - 1024px) */
@media (max-width: 1024px) and (min-width: 768px) {
.container {
padding: 15px;
}
.title {
font-size: 2.2rem;
}
.content-card {
padding: 35px;
max-width: 550px;
}
.kfc-content {
padding: 25px;
min-height: 180px;
}
.button-group {
flex-direction: row;
gap: 12px;
}
.generate-btn, .copy-btn {
padding: 12px 25px;
font-size: 0.95rem;
}
}
/* 手机端适配 (最大768px) */
@media (max-width: 768px) {
.container {
padding: 10px;
}
.header {
margin-bottom: 30px;
padding: 20px 0;
}
.title {
font-size: 1.8rem;
margin-bottom: 8px;
}
.subtitle {
font-size: 1rem;
}
.content-card {
padding: 25px;
margin: 0 5px;
border-radius: 15px;
}
.kfc-content {
padding: 20px;
min-height: 150px;
margin-bottom: 25px;
}
.kfc-content::before {
font-size: 2.5rem;
top: 5px;
left: 10px;
}
.kfc-content p {
font-size: 1rem;
line-height: 1.7;
margin-left: 15px;
}
.button-group {
flex-direction: column;
gap: 10px;
}
.generate-btn, .copy-btn {
padding: 12px 20px;
font-size: 0.9rem;
width: 100%;
}
.footer {
font-size: 0.8rem;
margin-top: 30px;
}
.toast {
right: 10px;
left: 10px;
transform: translateY(-100px);
font-size: 0.9rem;
}
.toast.show {
transform: translateY(0);
}
}
/* 小屏手机适配 (最大480px) */
@media (max-width: 480px) {
.title {
font-size: 1.6rem;
}
.content-card {
padding: 20px;
margin: 0;
}
.kfc-content {
padding: 15px;
min-height: 120px;
}
.kfc-content p {
font-size: 0.95rem;
margin-left: 10px;
}
.generate-btn, .copy-btn {
padding: 10px 15px;
font-size: 0.85rem;
}
}

View File

@@ -1,46 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>随机KFC文案生成器</title>
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="css/background.css">
</head>
<body>
<div class="container">
<header class="header">
<h1 class="title">🍗 随机KFC文案生成器</h1>
<p class="subtitle">疯狂星期四,文案来一套!</p>
</header>
<main class="main">
<div class="content-card">
<div class="kfc-content" id="kfcContent">
<p class="loading-text">点击按钮获取随机KFC文案...</p>
</div>
<div class="button-group">
<button class="generate-btn" id="generateBtn">
<span class="btn-text">生成文案</span>
<span class="btn-loading" style="display: none;">生成中...</span>
</button>
<button class="copy-btn" id="copyBtn" style="display: none;">复制文案</button>
</div>
<div class="index-info" id="indexInfo" style="display: none;">
<span class="index-text">文案编号: <span id="indexNumber"></span></span>
</div>
</div>
</main>
<footer class="footer">
<p>© 2024 KFC文案生成器 | 让每个星期四都疯狂起来</p>
</footer>
</div>
<div class="toast" id="toast"></div>
<script src="js/main.js"></script>
</body>
</html>

View File

@@ -1,240 +0,0 @@
// KFC文案生成器主要功能
class KFCGenerator {
constructor() {
this.apiEndpoints = [];
this.currentApiIndex = 0;
this.isLoading = false;
this.init();
}
// 初始化
async init() {
await this.loadApiEndpoints();
this.bindEvents();
}
// 加载API接口列表
async loadApiEndpoints() {
try {
const response = await fetch('./接口集合.json');
this.apiEndpoints = await response.json();
} catch (error) {
console.error('加载API接口列表失败:', error);
this.showToast('加载接口配置失败', 'error');
}
}
// 绑定事件
bindEvents() {
const generateBtn = document.getElementById('generateBtn');
const copyBtn = document.getElementById('copyBtn');
generateBtn.addEventListener('click', () => this.generateKFC());
copyBtn.addEventListener('click', () => this.copyContent());
}
// 生成KFC文案
async generateKFC() {
if (this.isLoading) return;
this.setLoadingState(true);
let success = false;
let attempts = 0;
const maxAttempts = this.apiEndpoints.length;
while (!success && attempts < maxAttempts) {
try {
const apiUrl = this.apiEndpoints[this.currentApiIndex];
const data = await this.fetchKFCData(apiUrl);
if (data && data.code === 200 && data.data && data.data.kfc) {
this.displayKFC(data.data);
success = true;
} else {
throw new Error('API返回数据格式错误');
}
} catch (error) {
console.error(`API ${this.currentApiIndex + 1} 请求失败:`, error);
this.currentApiIndex = (this.currentApiIndex + 1) % this.apiEndpoints.length;
attempts++;
}
}
if (!success) {
this.showError('所有API接口都无法访问请稍后重试');
}
this.setLoadingState(false);
}
// 请求KFC数据
async fetchKFCData(apiUrl) {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 10000); // 10秒超时
try {
const response = await fetch(`${apiUrl}/v2/kfc`, {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
signal: controller.signal
});
clearTimeout(timeoutId);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return await response.json();
} catch (error) {
clearTimeout(timeoutId);
throw error;
}
}
// 显示KFC文案
displayKFC(data) {
const contentElement = document.getElementById('kfcContent');
const indexElement = document.getElementById('indexNumber');
const indexInfo = document.getElementById('indexInfo');
const copyBtn = document.getElementById('copyBtn');
// 显示文案内容
contentElement.innerHTML = `<p>${this.escapeHtml(data.kfc)}</p>`;
// 显示编号信息
if (data.index) {
indexElement.textContent = data.index;
indexInfo.style.display = 'block';
} else {
indexInfo.style.display = 'none';
}
// 显示复制按钮
copyBtn.style.display = 'inline-block';
// 添加显示动画
contentElement.style.opacity = '0';
contentElement.style.transform = 'translateY(20px)';
setTimeout(() => {
contentElement.style.transition = 'all 0.5s ease';
contentElement.style.opacity = '1';
contentElement.style.transform = 'translateY(0)';
}, 100);
}
// 显示错误信息
showError(message) {
const contentElement = document.getElementById('kfcContent');
contentElement.innerHTML = `<p class="loading-text" style="color: #e74c3c;">${this.escapeHtml(message)}</p>`;
const copyBtn = document.getElementById('copyBtn');
const indexInfo = document.getElementById('indexInfo');
copyBtn.style.display = 'none';
indexInfo.style.display = 'none';
}
// 复制文案内容
async copyContent() {
const contentElement = document.getElementById('kfcContent');
const textContent = contentElement.querySelector('p')?.textContent;
if (!textContent || textContent.includes('点击按钮获取') || textContent.includes('失败')) {
this.showToast('没有可复制的内容', 'error');
return;
}
try {
if (navigator.clipboard && window.isSecureContext) {
await navigator.clipboard.writeText(textContent);
} else {
// 降级方案
const textArea = document.createElement('textarea');
textArea.value = textContent;
textArea.style.position = 'fixed';
textArea.style.left = '-999999px';
textArea.style.top = '-999999px';
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
document.execCommand('copy');
textArea.remove();
}
this.showToast('文案已复制到剪贴板', 'success');
} catch (error) {
console.error('复制失败:', error);
this.showToast('复制失败,请手动选择复制', 'error');
}
}
// 设置加载状态
setLoadingState(loading) {
this.isLoading = loading;
const generateBtn = document.getElementById('generateBtn');
const btnText = generateBtn.querySelector('.btn-text');
const btnLoading = generateBtn.querySelector('.btn-loading');
if (loading) {
generateBtn.disabled = true;
btnText.style.display = 'none';
btnLoading.style.display = 'inline';
} else {
generateBtn.disabled = false;
btnText.style.display = 'inline';
btnLoading.style.display = 'none';
}
}
// 显示提示消息
showToast(message, type = 'success') {
const toast = document.getElementById('toast');
toast.textContent = message;
toast.className = `toast ${type}`;
toast.classList.add('show');
setTimeout(() => {
toast.classList.remove('show');
}, 3000);
}
// HTML转义
escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
}
// 页面加载完成后初始化
document.addEventListener('DOMContentLoaded', () => {
const generator = new KFCGenerator();
// 页面加载完成后自动生成一条文案
setTimeout(() => {
generator.generateKFC();
}, 1000);
});
// 添加键盘快捷键支持
document.addEventListener('keydown', (event) => {
// 按空格键生成文案
if (event.code === 'Space' && event.target.tagName !== 'INPUT' && event.target.tagName !== 'TEXTAREA') {
event.preventDefault();
document.getElementById('generateBtn').click();
}
// Ctrl+C 复制文案
if (event.ctrlKey && event.key === 'c' && event.target.tagName !== 'INPUT' && event.target.tagName !== 'TEXTAREA') {
const copyBtn = document.getElementById('copyBtn');
if (copyBtn.style.display !== 'none') {
event.preventDefault();
copyBtn.click();
}
}
});

View File

@@ -1,7 +0,0 @@
[
"https://60s-cf.viki.moe",
"https://60s.viki.moe",
"https://60s.b23.run",
"https://60s.114128.xyz",
"https://60s-cf.114128.xyz"
]

View File

@@ -1 +0,0 @@
{"code":200,"message":"获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s反馈群 595941841","data":{"index":369,"kfc":"我不想你带着情绪过夜,这样会把你推的越来越远,我不想你离开我,我希望你可以多爱我一点,我不想因为一点点小问题就让我们两之间的感情产生隔阂。对我来说,双向奔赴的感情相处才有意义,看不到希望的事情我没办法坚持太久,我不想浪费时间在一些无意义无结果的事情上,时间应该用来做我该做的事情。很多人走不到最后,是因为理解不同步,但我跟你在一起,我知道你什样的人,我了解你甚至比了解自己还多,我和你在一起,不是因为其他,而是因为今天肯德基疯狂星期四,我希望你能请我吃!"}}

View File

@@ -1,167 +0,0 @@
/* 背景样式文件 - 金色光辉主题 */
/* 主背景 */
body {
background: linear-gradient(
135deg,
#fff8dc 0%,
#ffeaa7 25%,
#fdcb6e 50%,
#e17055 75%,
#d63031 100%
);
background-size: 400% 400%;
animation: gradientShift 15s ease infinite;
position: relative;
}
/* 背景装饰层 */
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background:
radial-gradient(circle at 20% 80%, rgba(255, 215, 0, 0.1) 0%, transparent 50%),
radial-gradient(circle at 80% 20%, rgba(255, 223, 0, 0.1) 0%, transparent 50%),
radial-gradient(circle at 40% 40%, rgba(212, 175, 55, 0.05) 0%, transparent 50%);
pointer-events: none;
z-index: 1;
}
/* 动态光点效果 */
body::after {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image:
radial-gradient(2px 2px at 20px 30px, rgba(255, 215, 0, 0.3), transparent),
radial-gradient(2px 2px at 40px 70px, rgba(255, 223, 0, 0.2), transparent),
radial-gradient(1px 1px at 90px 40px, rgba(212, 175, 55, 0.4), transparent),
radial-gradient(1px 1px at 130px 80px, rgba(255, 215, 0, 0.2), transparent),
radial-gradient(2px 2px at 160px 30px, rgba(255, 223, 0, 0.3), transparent);
background-repeat: repeat;
background-size: 200px 100px;
animation: sparkle 20s linear infinite;
pointer-events: none;
z-index: 2;
}
/* 背景动画 */
@keyframes gradientShift {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
@keyframes sparkle {
0% {
transform: translateY(0);
opacity: 1;
}
100% {
transform: translateY(-100vh);
opacity: 0;
}
}
/* 响应式背景调整 */
/* 平板端背景 */
@media (min-width: 768px) and (max-width: 1024px) {
body::after {
background-size: 250px 120px;
}
}
/* 电脑端背景 */
@media (min-width: 1024px) {
body {
background-size: 300% 300%;
}
body::after {
background-size: 300px 150px;
animation-duration: 25s;
}
}
/* 手机端背景优化 */
@media (max-width: 767px) {
body {
background-size: 200% 200%;
animation-duration: 10s;
}
body::before {
background:
radial-gradient(circle at 30% 70%, rgba(255, 215, 0, 0.08) 0%, transparent 40%),
radial-gradient(circle at 70% 30%, rgba(255, 223, 0, 0.08) 0%, transparent 40%);
}
body::after {
background-size: 150px 80px;
animation-duration: 15s;
}
}
/* 超小屏幕背景 */
@media (max-width: 479px) {
body {
background: linear-gradient(
135deg,
#fff8dc 0%,
#ffeaa7 50%,
#fdcb6e 100%
);
background-size: 150% 150%;
}
body::after {
background-size: 120px 60px;
}
}
/* 深色模式支持 */
@media (prefers-color-scheme: dark) {
body {
background: linear-gradient(
135deg,
#2c1810 0%,
#3d2914 25%,
#4a3319 50%,
#5c3e1f 75%,
#6b4423 100%
);
}
body::before {
background:
radial-gradient(circle at 20% 80%, rgba(255, 215, 0, 0.05) 0%, transparent 50%),
radial-gradient(circle at 80% 20%, rgba(255, 223, 0, 0.05) 0%, transparent 50%);
}
}
/* 减少动画效果(用户偏好) */
@media (prefers-reduced-motion: reduce) {
body,
body::before,
body::after {
animation: none;
}
body {
background: linear-gradient(135deg, #fff8dc 0%, #ffeaa7 50%, #fdcb6e 100%);
}
}

View File

@@ -1,357 +0,0 @@
/* 基础样式重置 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Microsoft YaHei', 'PingFang SC', 'Helvetica Neue', Arial, sans-serif;
line-height: 1.6;
color: #2c1810;
overflow-x: hidden;
}
/* 容器布局 */
.container {
min-height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 20px;
position: relative;
}
/* 头部样式 */
.header {
text-align: center;
margin-bottom: 40px;
z-index: 10;
}
.title {
font-size: 3rem;
font-weight: 700;
color: #d4af37;
text-shadow:
0 0 10px rgba(212, 175, 55, 0.8),
0 0 20px rgba(212, 175, 55, 0.6),
0 0 30px rgba(212, 175, 55, 0.4);
margin-bottom: 10px;
animation: titleGlow 3s ease-in-out infinite alternate;
}
.subtitle {
font-size: 1.2rem;
color: #b8860b;
opacity: 0.9;
text-shadow: 0 0 5px rgba(184, 134, 11, 0.5);
}
/* 主内容区域 */
.main-content {
width: 100%;
max-width: 800px;
z-index: 10;
}
/* 一言容器 */
.quote-container {
background: linear-gradient(135deg, rgba(255, 215, 0, 0.1), rgba(255, 223, 0, 0.05));
border: 2px solid rgba(212, 175, 55, 0.3);
border-radius: 20px;
padding: 40px;
margin-bottom: 30px;
backdrop-filter: blur(10px);
box-shadow:
0 8px 32px rgba(212, 175, 55, 0.2),
inset 0 1px 0 rgba(255, 255, 255, 0.1);
position: relative;
overflow: hidden;
}
.quote-container::before {
content: '';
position: absolute;
top: -2px;
left: -2px;
right: -2px;
bottom: -2px;
background: linear-gradient(45deg, #ffd700, #ffed4e, #ffd700, #ffed4e);
border-radius: 22px;
z-index: -1;
animation: borderGlow 4s linear infinite;
}
/* 加载状态 */
.loading {
display: none;
text-align: center;
color: #d4af37;
}
.loading.show {
display: block;
}
.loading-spinner {
width: 40px;
height: 40px;
border: 4px solid rgba(212, 175, 55, 0.3);
border-top: 4px solid #d4af37;
border-radius: 50%;
margin: 0 auto 15px;
animation: spin 1s linear infinite;
}
/* 一言显示 */
.quote-display {
display: block;
text-align: center;
}
.quote-display.hide {
display: none;
}
.quote-text {
font-size: 1.8rem;
line-height: 1.8;
color: #2c1810;
margin-bottom: 20px;
text-shadow: 0 1px 2px rgba(212, 175, 55, 0.1);
font-weight: 500;
}
.quote-index {
font-size: 0.9rem;
color: #b8860b;
opacity: 0.8;
}
/* 错误信息 */
.error-message {
display: none;
text-align: center;
color: #cd853f;
}
.error-message.show {
display: block;
}
.error-icon {
font-size: 2rem;
margin-bottom: 10px;
}
.error-text {
font-size: 1.1rem;
line-height: 1.5;
}
/* 控制按钮 */
.controls {
text-align: center;
}
.refresh-btn {
background: linear-gradient(135deg, #ffd700, #ffed4e);
border: none;
border-radius: 50px;
padding: 15px 30px;
font-size: 1.1rem;
font-weight: 600;
color: #2c1810;
cursor: pointer;
display: inline-flex;
align-items: center;
gap: 10px;
transition: all 0.3s ease;
box-shadow:
0 4px 15px rgba(212, 175, 55, 0.3),
inset 0 1px 0 rgba(255, 255, 255, 0.3);
position: relative;
overflow: hidden;
}
.refresh-btn:hover {
transform: translateY(-2px);
box-shadow:
0 6px 20px rgba(212, 175, 55, 0.4),
inset 0 1px 0 rgba(255, 255, 255, 0.3);
}
.refresh-btn:active {
transform: translateY(0);
}
.refresh-btn:disabled {
opacity: 0.6;
cursor: not-allowed;
transform: none;
}
.btn-icon {
font-size: 1.2rem;
transition: transform 0.3s ease;
}
.refresh-btn:hover .btn-icon {
transform: rotate(180deg);
}
/* 底部 */
.footer {
margin-top: 40px;
text-align: center;
color: #b8860b;
opacity: 0.8;
font-size: 0.9rem;
}
/* 动画效果 */
@keyframes titleGlow {
0% {
text-shadow:
0 0 10px rgba(212, 175, 55, 0.8),
0 0 20px rgba(212, 175, 55, 0.6),
0 0 30px rgba(212, 175, 55, 0.4);
}
100% {
text-shadow:
0 0 15px rgba(212, 175, 55, 1),
0 0 25px rgba(212, 175, 55, 0.8),
0 0 35px rgba(212, 175, 55, 0.6);
}
}
@keyframes borderGlow {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* 平板端适配 (768px - 1024px) */
@media (min-width: 768px) and (max-width: 1024px) {
.container {
padding: 30px;
}
.title {
font-size: 3.5rem;
}
.subtitle {
font-size: 1.3rem;
}
.quote-container {
padding: 50px;
}
.quote-text {
font-size: 2rem;
}
}
/* 电脑端适配 (1024px+) */
@media (min-width: 1024px) {
.container {
padding: 40px;
}
.title {
font-size: 4rem;
}
.subtitle {
font-size: 1.4rem;
}
.quote-container {
padding: 60px;
max-width: 900px;
}
.quote-text {
font-size: 2.2rem;
line-height: 1.9;
}
.refresh-btn {
padding: 18px 36px;
font-size: 1.2rem;
}
}
/* 手机端适配 (小于768px) */
@media (max-width: 767px) {
.container {
padding: 15px;
}
.header {
margin-bottom: 30px;
}
.title {
font-size: 2.5rem;
}
.subtitle {
font-size: 1rem;
}
.quote-container {
padding: 25px;
border-radius: 15px;
}
.quote-text {
font-size: 1.4rem;
line-height: 1.6;
}
.refresh-btn {
padding: 12px 24px;
font-size: 1rem;
}
.footer {
margin-top: 30px;
font-size: 0.8rem;
}
}
/* 超小屏幕适配 (小于480px) */
@media (max-width: 479px) {
.title {
font-size: 2rem;
}
.quote-container {
padding: 20px;
}
.quote-text {
font-size: 1.2rem;
}
.refresh-btn {
padding: 10px 20px;
font-size: 0.9rem;
}
}

View File

@@ -1,52 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>随机一言 - 金色光辉</title>
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="css/background.css">
</head>
<body>
<div class="container">
<header class="header">
<h1 class="title">随机一言</h1>
<p class="subtitle">每一句话都是心灵的光芒</p>
</header>
<main class="main-content">
<div class="quote-container">
<div class="loading" id="loading">
<div class="loading-spinner"></div>
<p>正在获取一言...</p>
</div>
<div class="quote-display" id="quoteDisplay">
<div class="quote-text" id="quoteText">
点击下方按钮获取一言
</div>
<div class="quote-index" id="quoteIndex"></div>
</div>
<div class="error-message" id="errorMessage">
<div class="error-icon">⚠️</div>
<div class="error-text" id="errorText"></div>
</div>
</div>
<div class="controls">
<button class="refresh-btn" id="refreshBtn">
<span class="btn-icon">🔄</span>
<span class="btn-text">获取新一言</span>
</button>
</div>
</main>
<footer class="footer">
<p>愿每一句话都能温暖你的心</p>
</footer>
</div>
<script src="js/script.js"></script>
</body>
</html>

View File

@@ -1,225 +0,0 @@
// 随机一言 JavaScript 功能实现
class HitokotoApp {
constructor() {
// API接口列表
this.apiEndpoints = [
"https://60s-cf.viki.moe",
"https://60s.viki.moe",
"https://60s.b23.run",
"https://60s.114128.xyz",
"https://60s-cf.114128.xyz"
];
this.currentEndpointIndex = 0;
this.isLoading = false;
// DOM 元素
this.elements = {
loading: document.getElementById('loading'),
quoteDisplay: document.getElementById('quoteDisplay'),
quoteText: document.getElementById('quoteText'),
quoteIndex: document.getElementById('quoteIndex'),
errorMessage: document.getElementById('errorMessage'),
errorText: document.getElementById('errorText'),
refreshBtn: document.getElementById('refreshBtn')
};
this.init();
}
// 初始化应用
init() {
this.bindEvents();
this.hideAllStates();
this.showQuoteDisplay();
}
// 绑定事件
bindEvents() {
this.elements.refreshBtn.addEventListener('click', () => {
this.fetchHitokoto();
});
// 键盘快捷键支持
document.addEventListener('keydown', (e) => {
if (e.code === 'Space' && !this.isLoading) {
e.preventDefault();
this.fetchHitokoto();
}
});
}
// 隐藏所有状态
hideAllStates() {
this.elements.loading.classList.remove('show');
this.elements.quoteDisplay.classList.remove('hide');
this.elements.errorMessage.classList.remove('show');
}
// 显示加载状态
showLoading() {
this.hideAllStates();
this.elements.loading.classList.add('show');
this.elements.quoteDisplay.classList.add('hide');
this.elements.refreshBtn.disabled = true;
this.isLoading = true;
}
// 显示一言内容
showQuoteDisplay() {
this.hideAllStates();
this.elements.quoteDisplay.classList.remove('hide');
this.elements.refreshBtn.disabled = false;
this.isLoading = false;
}
// 显示错误信息
showError(message) {
this.hideAllStates();
this.elements.errorMessage.classList.add('show');
this.elements.errorText.textContent = message;
this.elements.refreshBtn.disabled = false;
this.isLoading = false;
}
// 获取一言数据
async fetchHitokoto() {
if (this.isLoading) return;
this.showLoading();
// 尝试所有API接口
for (let i = 0; i < this.apiEndpoints.length; i++) {
const endpointIndex = (this.currentEndpointIndex + i) % this.apiEndpoints.length;
const endpoint = this.apiEndpoints[endpointIndex];
try {
const result = await this.tryFetchFromEndpoint(endpoint);
if (result.success) {
this.currentEndpointIndex = endpointIndex;
this.displayHitokoto(result.data);
return;
}
} catch (error) {
console.warn(`接口 ${endpoint} 请求失败:`, error.message);
continue;
}
}
// 所有接口都失败
this.showError('所有接口都无法访问,请检查网络连接或稍后重试');
}
// 尝试从指定接口获取数据
async tryFetchFromEndpoint(endpoint) {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 10000); // 10秒超时
try {
const response = await fetch(`${endpoint}/v2/hitokoto?encoding=text`, {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
signal: controller.signal
});
clearTimeout(timeoutId);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const data = await response.json();
// 验证返回数据格式
if (data.code === 200 && data.data && data.data.hitokoto) {
return {
success: true,
data: data.data
};
} else {
throw new Error('返回数据格式不正确');
}
} catch (error) {
clearTimeout(timeoutId);
if (error.name === 'AbortError') {
throw new Error('请求超时');
}
throw error;
}
}
// 显示一言内容
displayHitokoto(data) {
// 更新一言文本
this.elements.quoteText.textContent = data.hitokoto;
// 更新序号信息
if (data.index) {
this.elements.quoteIndex.textContent = `${data.index}`;
} else {
this.elements.quoteIndex.textContent = '';
}
// 添加淡入动画效果
this.elements.quoteText.style.opacity = '0';
this.elements.quoteIndex.style.opacity = '0';
setTimeout(() => {
this.elements.quoteText.style.transition = 'opacity 0.5s ease';
this.elements.quoteIndex.style.transition = 'opacity 0.5s ease';
this.elements.quoteText.style.opacity = '1';
this.elements.quoteIndex.style.opacity = '1';
}, 100);
this.showQuoteDisplay();
// 控制台输出调试信息
console.log('一言获取成功:', {
content: data.hitokoto,
index: data.index,
endpoint: this.apiEndpoints[this.currentEndpointIndex]
});
}
// 获取随机接口(用于负载均衡)
getRandomEndpoint() {
const randomIndex = Math.floor(Math.random() * this.apiEndpoints.length);
return this.apiEndpoints[randomIndex];
}
}
// 页面加载完成后初始化应用
document.addEventListener('DOMContentLoaded', () => {
const app = new HitokotoApp();
// 添加全局错误处理
window.addEventListener('error', (event) => {
console.error('页面发生错误:', event.error);
});
window.addEventListener('unhandledrejection', (event) => {
console.error('未处理的Promise拒绝:', event.reason);
});
// 页面可见性变化时的处理
document.addEventListener('visibilitychange', () => {
if (!document.hidden && !app.isLoading) {
// 页面重新可见时,可以选择刷新内容
console.log('页面重新可见');
}
});
console.log('随机一言应用初始化完成');
});
// 导出应用类(如果需要在其他地方使用)
if (typeof module !== 'undefined' && module.exports) {
module.exports = HitokotoApp;
}

View File

@@ -1,7 +0,0 @@
[
"https://60s-cf.viki.moe",
"https://60s.viki.moe",
"https://60s.b23.run",
"https://60s.114128.xyz",
"https://60s-cf.114128.xyz"
]

View File

@@ -1,8 +0,0 @@
{
"code": 200,
"message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s反馈群 595941841",
"data": {
"index": 2862,
"hitokoto": "你带上罪恶之冠,即使背负上所有罪恶和孤独,绝不让你受伤"
}
}

View File

@@ -1,251 +0,0 @@
/* 随机唱歌音频 - 淡绿色清新风格样式 */
/* 重置样式 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #a8e6cf 0%, #dcedc1 50%, #ffd3a5 100%);
min-height: 100vh;
color: #2d5016;
line-height: 1.6;
overflow-x: hidden;
}
.container {
max-width: 900px;
margin: 0 auto;
padding: 20px;
}
/* 头部 */
.header {
text-align: center;
margin-bottom: 20px;
background: rgba(255, 255, 255, 0.85);
border-radius: 20px;
padding: 24px;
box-shadow: 0 8px 25px rgba(45, 80, 22, 0.08);
backdrop-filter: blur(10px);
}
.header h1 {
font-size: 2rem;
color: #2d5016;
margin-bottom: 10px;
font-weight: 700;
display: flex;
align-items: center;
justify-content: center;
gap: 12px;
}
.header p {
color: #5a7c65;
font-size: 1rem;
}
/* 用户卡片 */
.user-card {
display: flex;
align-items: center;
justify-content: center;
gap: 15px;
background: rgba(255, 255, 255, 0.9);
padding: 16px;
border-radius: 15px;
box-shadow: 0 4px 18px rgba(45, 80, 22, 0.08);
margin-bottom: 15px;
text-align: center;
}
.avatar {
width: 56px;
height: 56px;
border-radius: 50%;
object-fit: cover;
border: 3px solid rgba(129, 199, 132, 0.5);
}
.user-info {
display: flex;
flex-direction: column;
}
.nickname {
font-weight: 700;
font-size: 1.1rem;
color: #2d5016;
}
.meta {
color: #5a7c65;
font-size: 0.9rem;
}
/* 歌曲信息 */
.song-card {
background: rgba(255, 255, 255, 0.9);
padding: 16px;
border-radius: 15px;
box-shadow: 0 4px 18px rgba(45, 80, 22, 0.08);
margin-bottom: 15px;
text-align: center;
}
.song-title {
font-size: 1.2rem;
font-weight: 700;
margin-bottom: 8px;
color: #1b5e20;
}
.song-meta {
color: #5a7c65;
font-size: 0.95rem;
margin-bottom: 10px;
}
/* 歌词 */
.lyrics {
background: rgba(129, 199, 132, 0.1);
border-radius: 12px;
padding: 12px;
max-height: 220px;
overflow: auto;
}
.lyrics p {
margin-bottom: 6px;
}
/* 音频播放器卡片 */
.audio-card {
background: rgba(255, 255, 255, 0.9);
padding: 16px;
border-radius: 15px;
box-shadow: 0 4px 18px rgba(45, 80, 22, 0.08);
margin-bottom: 15px;
}
.audio-actions {
display: flex;
flex-direction: column;
gap: 12px;
align-items: center;
margin-top: 10px;
}
.btn {
background: linear-gradient(135deg, #81c784 0%, #66bb6a 100%);
color: white;
border: none;
padding: 10px 18px;
border-radius: 10px;
font-size: 0.95rem;
font-weight: 600;
cursor: pointer;
transition: all 0.25s ease;
box-shadow: 0 4px 12px rgba(129, 199, 132, 0.35);
text-decoration: none;
}
.btn:hover {
transform: translateY(-2px);
box-shadow: 0 6px 18px rgba(129, 199, 132, 0.45);
}
.info {
color: #5a7c65;
font-size: 0.9rem;
}
/* 加载与错误 */
.loading, .error {
text-align: center;
padding: 30px;
background: rgba(255, 255, 255, 0.85);
border-radius: 15px;
box-shadow: 0 5px 20px rgba(45, 80, 22, 0.08);
}
.spinner {
width: 36px;
height: 36px;
border: 4px solid #e8f5e8;
border-top: 4px solid #81c784;
border-radius: 50%;
animation: spin 1s linear infinite;
margin: 0 auto 18px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* 动画 */
.fade-in {
animation: fadeIn 0.5s ease-in-out;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
/* 平板端适配 */
@media (max-width: 1024px) and (min-width: 768px) {
.container { padding: 16px; }
.header h1 { font-size: 1.8rem; }
}
/* 手机端优先优化 */
@media (max-width: 767px) {
.container { padding: 12px; }
.header { padding: 18px; }
.header h1 { font-size: 1.6rem; gap: 8px; }
.user-card {
padding: 16px;
flex-direction: column;
text-align: center;
}
.avatar {
width: 80px;
height: 80px;
margin-bottom: 8px;
}
.song-card, .audio-card {
padding: 16px;
}
.lyrics {
max-height: 180px;
text-align: left;
padding: 16px;
}
.audio-actions {
flex-direction: column;
gap: 15px;
align-items: center;
}
.info {
text-align: center;
line-height: 1.8;
}
.btn {
width: 100%;
max-width: 200px;
text-align: center;
}
}

View File

@@ -1,67 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>随机唱歌音频 - 60s API 集合</title>
<meta name="description" content="随机唱歌音频,数据源自 60s.viki.moe提供用户信息、歌曲信息、歌词与音频播放。" />
<link rel="stylesheet" href="./css/style.css" />
</head>
<body>
<div class="container">
<header class="header">
<h1>
🎵 随机唱歌音频
</h1>
<p>数据来自官方/权威源头,以确保稳定与实时 · 支持本地数据回退</p>
</header>
<!-- 加载与错误状态 -->
<section id="loading" class="loading">
<div class="spinner"></div>
<p>正在加载中,请稍候…</p>
</section>
<section id="error" class="error" style="display: none;">
<p>获取数据失败,请稍后重试</p>
</section>
<!-- 内容区域 -->
<main id="content" style="display: none;" class="fade-in">
<!-- 用户信息 -->
<div class="user-card">
<img id="avatar" class="avatar" src="" alt="用户头像" />
<div class="user-info">
<div class="nickname" id="nickname">-</div>
<div class="meta">性别:<span id="gender">-</span></div>
</div>
</div>
<!-- 歌曲信息 -->
<div class="song-card">
<div class="song-title" id="song-title">-</div>
<div class="song-meta" id="song-meta">-</div>
<div class="lyrics" id="lyrics"></div>
</div>
<!-- 音频播放 -->
<div class="audio-card">
<audio id="audio" controls style="width: 100%;"></audio>
<div class="audio-actions">
<button class="btn" id="refresh-btn">换一首</button>
<div class="info">
❤ 喜欢:<span id="like-count">-</span>
· ⏱ 时长:<span id="duration">--:--</span>
· 🗓 发布:<span id="publish-time">-</span>
· 🔗 <a id="link" href="#" class="btn" style="padding: 6px 10px; border-radius: 8px; background: #81c784;">查看原帖</a>
</div>
</div>
</div>
</main>
</div>
<script src="./js/script.js"></script>
</body>
</html>

View File

@@ -1,252 +0,0 @@
// 随机唱歌音频 页面脚本
(function () {
'use strict';
const API = {
endpoints: [],
currentIndex: 0,
params: {
encoding: 'json'
},
localFallback: '返回接口.json',
// 初始化API接口列表
async init() {
try {
const res = await fetch('./接口集合.json');
const endpoints = await res.json();
this.endpoints = endpoints.map(endpoint => `${endpoint}/v2/changya`);
} catch (e) {
// 如果无法加载接口集合,使用默认接口
this.endpoints = ['https://60s.viki.moe/v2/changya'];
}
},
// 获取当前接口URL
getCurrentUrl() {
if (this.endpoints.length === 0) return null;
const url = new URL(this.endpoints[this.currentIndex]);
Object.entries(this.params).forEach(([k, v]) => url.searchParams.append(k, v));
return url.toString();
},
// 切换到下一个接口
switchToNext() {
this.currentIndex = (this.currentIndex + 1) % this.endpoints.length;
return this.currentIndex < this.endpoints.length;
},
// 重置到第一个接口
reset() {
this.currentIndex = 0;
}
};
// DOM 元素引用
const els = {
loading: null,
error: null,
container: null,
avatar: null,
nickname: null,
gender: null,
songTitle: null,
songMeta: null,
lyrics: null,
audio: null,
likeCount: null,
publishTime: null,
link: null,
refreshBtn: null,
};
function initDom() {
els.loading = document.getElementById('loading');
els.error = document.getElementById('error');
els.container = document.getElementById('content');
els.avatar = document.getElementById('avatar');
els.nickname = document.getElementById('nickname');
els.gender = document.getElementById('gender');
els.songTitle = document.getElementById('song-title');
els.songMeta = document.getElementById('song-meta');
els.lyrics = document.getElementById('lyrics');
els.audio = document.getElementById('audio');
els.likeCount = document.getElementById('like-count');
els.publishTime = document.getElementById('publish-time');
els.link = document.getElementById('link');
els.refreshBtn = document.getElementById('refresh-btn');
}
function showLoading() {
els.loading.style.display = 'block';
els.error.style.display = 'none';
els.container.style.display = 'none';
}
function showError(msg) {
els.loading.style.display = 'none';
els.error.style.display = 'block';
els.container.style.display = 'none';
els.error.querySelector('p').textContent = msg || '获取数据失败,请稍后重试';
}
function showContent() {
els.loading.style.display = 'none';
els.error.style.display = 'none';
els.container.style.display = 'block';
}
function formatDuration(ms) {
if (!ms && ms !== 0) return '';
const totalSeconds = Math.floor(ms / 1000);
const m = Math.floor(totalSeconds / 60).toString().padStart(2, '0');
const s = (totalSeconds % 60).toString().padStart(2, '0');
return `${m}:${s}`;
}
function safeText(text) {
const div = document.createElement('div');
div.textContent = text == null ? '' : String(text);
return div.innerHTML;
}
async function fetchFromAPI() {
// 初始化API接口列表
await API.init();
// 重置API索引到第一个接口
API.reset();
// 尝试所有API接口
for (let i = 0; i < API.endpoints.length; i++) {
try {
const url = API.getCurrentUrl();
console.log(`尝试接口 ${i + 1}/${API.endpoints.length}: ${url}`);
const resp = await fetch(url, {
cache: 'no-store',
timeout: 10000 // 10秒超时
});
if (!resp.ok) {
throw new Error(`HTTP ${resp.status}: ${resp.statusText}`);
}
const data = await resp.json();
if (data && data.code === 200) {
console.log(`接口 ${i + 1} 请求成功`);
return data;
}
throw new Error(data && data.message ? data.message : '接口返回异常');
} catch (e) {
console.warn(`接口 ${i + 1} 失败:`, e.message);
// 如果不是最后一个接口,切换到下一个
if (i < API.endpoints.length - 1) {
API.switchToNext();
continue;
}
// 所有接口都失败了
console.warn('所有远程接口都失败,尝试本地数据');
return null;
}
}
}
async function fetchFromLocal() {
try {
const resp = await fetch(API.localFallback + `?t=${Date.now()}`);
if (!resp.ok) throw new Error(`本地文件HTTP ${resp.status}`);
const data = await resp.json();
return data;
} catch (e) {
console.error('读取本地返回接口.json失败:', e);
return null;
}
}
function render(data) {
const d = data?.data || {};
const user = d.user || {};
const song = d.song || {};
const audio = d.audio || {};
// 用户信息
els.avatar.src = user.avatar_url || '';
els.avatar.alt = (user.nickname || '用户') + ' 头像';
els.nickname.textContent = user.nickname || '未知用户';
els.gender.textContent = user.gender === 'female' ? '女' : user.gender === 'male' ? '男' : '未知';
// 歌曲信息
els.songTitle.textContent = song.name || '未知歌曲';
els.songMeta.textContent = song.singer ? `演唱:${song.singer}` : '';
els.lyrics.innerHTML = '';
if (Array.isArray(song.lyrics)) {
const frag = document.createDocumentFragment();
song.lyrics.forEach(line => {
const p = document.createElement('p');
p.innerHTML = safeText(line);
frag.appendChild(p);
});
els.lyrics.appendChild(frag);
}
// 音频
els.audio.src = audio.url || '';
els.audio.preload = 'none';
// 其他信息
els.likeCount.textContent = typeof audio.like_count === 'number' ? audio.like_count : '-';
const publish = audio.publish || (audio.publish_at ? new Date(audio.publish_at).toLocaleString() : '');
els.publishTime.textContent = publish;
els.link.href = audio.link || '#';
els.link.target = '_blank';
// 时长信息
const durationEl = document.getElementById('duration');
durationEl.textContent = formatDuration(audio.duration);
showContent();
}
async function load() {
showLoading();
try {
// 先尝试远程API
const data = await fetchFromAPI();
if (data) {
render(data);
return;
}
// 远程API失败尝试本地数据
const localData = await fetchFromLocal();
if (localData) {
render(localData);
return;
}
// 都失败了
showError('获取数据失败,请稍后重试');
} catch (e) {
console.error('加载数据时发生错误:', e);
showError('获取数据失败,请稍后重试');
}
}
function bindEvents() {
if (els.refreshBtn) {
els.refreshBtn.addEventListener('click', load);
}
// 快捷键 Ctrl+R 刷新(不拦截浏览器默认刷新)
}
document.addEventListener('DOMContentLoaded', () => {
initDom();
bindEvents();
load();
});
})();

View File

@@ -1,7 +0,0 @@
[
"https://60s-cf.viki.moe",
"https://60s.viki.moe",
"https://60s.b23.run",
"https://60s.114128.xyz",
"https://60s-cf.114128.xyz"
]

View File

@@ -1,32 +0,0 @@
{
"code": 200,
"message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s反馈群 595941841",
"data": {
"user": {
"nickname": "𝑮𝑺_迷鹿_",
"gender": "female",
"avatar_url": "http://img-cdn.api.singduck.cn/user-img/6afbebcfae6144478c150d0c1d0d5899.jpg"
},
"song": {
"name": "恶作剧",
"singer": "王蓝茵",
"lyrics": [
"我想我会开始想念你",
"可是我刚刚才遇见了你",
"我怀疑这奇遇只是个恶作剧",
"我想我已慢慢喜欢你",
"因为我拥有爱情的勇气",
"我任性投入你给的恶作剧",
"你给的恶作剧"
]
},
"audio": {
"url": "http://audio-cdn.api.singduck.cn/ugc/220929_965696173_b822a290c553.wav?auth_key=1755845643-0-0-4029539b73e17337dcac49cc4e0ecfcc",
"duration": 35050,
"like_count": 955,
"link": "https://m.api.singduck.cn/user-piece/toGZlBfZbukck2sHb",
"publish": "2022/09/29 18:33:51",
"publish_at": 1664447631000
}
}
}

View File

@@ -1,330 +0,0 @@
/* Epic Games 免费游戏 - 淡绿色清新风格样式 */
/* 重置样式 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #a8e6cf 0%, #dcedc1 50%, #ffd3a5 100%);
min-height: 100vh;
color: #2d5016;
line-height: 1.6;
overflow-x: hidden;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
/* 头部 */
.header {
text-align: center;
margin-bottom: 30px;
background: rgba(255, 255, 255, 0.85);
border-radius: 20px;
padding: 24px;
box-shadow: 0 8px 25px rgba(45, 80, 22, 0.08);
backdrop-filter: blur(10px);
}
.header h1 {
font-size: 2.2rem;
color: #2d5016;
margin-bottom: 10px;
font-weight: 700;
display: flex;
align-items: center;
justify-content: center;
gap: 12px;
}
.header p {
color: #5a7c65;
font-size: 1rem;
}
/* 统计信息 */
.stats {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 15px;
margin-bottom: 25px;
}
.stat-card {
background: rgba(255, 255, 255, 0.9);
padding: 16px;
border-radius: 15px;
text-align: center;
box-shadow: 0 4px 18px rgba(45, 80, 22, 0.08);
}
.stat-number {
font-size: 1.8rem;
font-weight: 700;
color: #1b5e20;
margin-bottom: 5px;
}
.stat-label {
color: #5a7c65;
font-size: 0.9rem;
}
/* 游戏网格 */
.games-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
gap: 20px;
margin-bottom: 20px;
}
/* 游戏卡片 */
.game-card {
background: rgba(255, 255, 255, 0.95);
border-radius: 18px;
overflow: hidden;
box-shadow: 0 6px 25px rgba(45, 80, 22, 0.1);
transition: all 0.3s ease;
position: relative;
}
.game-card:hover {
transform: translateY(-5px);
box-shadow: 0 12px 35px rgba(45, 80, 22, 0.15);
}
.game-cover {
width: 100%;
height: 180px;
object-fit: cover;
border-radius: 0;
}
.game-info {
padding: 18px;
}
.game-title {
font-size: 1.1rem;
font-weight: 700;
color: #1b5e20;
margin-bottom: 8px;
line-height: 1.3;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.game-description {
color: #5a7c65;
font-size: 0.9rem;
margin-bottom: 12px;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
line-height: 1.4;
}
.game-meta {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 12px;
}
.game-price {
font-size: 1rem;
font-weight: 600;
}
.original-price {
color: #81c784;
text-decoration: line-through;
}
.free-price {
color: #2e7d32;
font-weight: 700;
}
.game-seller {
color: #5a7c65;
font-size: 0.85rem;
}
.game-dates {
background: rgba(129, 199, 132, 0.1);
padding: 10px;
border-radius: 10px;
margin-bottom: 12px;
font-size: 0.85rem;
color: #2d5016;
}
.free-period {
display: flex;
justify-content: space-between;
margin-bottom: 4px;
}
.game-actions {
display: flex;
gap: 10px;
}
.btn {
flex: 1;
background: linear-gradient(135deg, #81c784 0%, #66bb6a 100%);
color: white;
border: none;
padding: 10px 16px;
border-radius: 10px;
font-size: 0.9rem;
font-weight: 600;
cursor: pointer;
transition: all 0.25s ease;
box-shadow: 0 4px 12px rgba(129, 199, 132, 0.35);
text-decoration: none;
text-align: center;
display: inline-block;
}
.btn:hover {
transform: translateY(-2px);
box-shadow: 0 6px 18px rgba(129, 199, 132, 0.45);
}
.btn-secondary {
background: linear-gradient(135deg, #a5d6a7 0%, #81c784 100%);
}
/* 状态标签 */
.status-badge {
position: absolute;
top: 12px;
right: 12px;
padding: 6px 12px;
border-radius: 20px;
font-size: 0.8rem;
font-weight: 600;
color: white;
text-shadow: 0 1px 2px rgba(0,0,0,0.2);
}
.status-free {
background: linear-gradient(135deg, #4caf50 0%, #2e7d32 100%);
}
.status-upcoming {
background: linear-gradient(135deg, #ff9800 0%, #f57c00 100%);
}
/* 加载与错误 */
.loading, .error {
text-align: center;
padding: 40px;
background: rgba(255, 255, 255, 0.85);
border-radius: 15px;
box-shadow: 0 5px 20px rgba(45, 80, 22, 0.08);
}
.spinner {
width: 40px;
height: 40px;
border: 4px solid #e8f5e8;
border-top: 4px solid #81c784;
border-radius: 50%;
animation: spin 1s linear infinite;
margin: 0 auto 20px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* 动画 */
.fade-in {
animation: fadeIn 0.6s ease-in-out;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
/* 平板端适配 */
@media (max-width: 1024px) and (min-width: 768px) {
.container { padding: 16px; }
.header h1 { font-size: 2rem; }
.games-grid { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
}
/* 手机端优化 */
@media (max-width: 767px) {
.container { padding: 12px; }
.header { padding: 18px; }
.header h1 { font-size: 1.8rem; gap: 8px; }
.stats {
display: flex;
flex-direction: row;
justify-content: space-between;
gap: 8px;
}
.stat-card {
padding: 10px 8px;
flex: 1;
min-width: 0;
}
.stat-number { font-size: 1.4rem; }
.stat-label { font-size: 0.75rem; }
.games-grid {
grid-template-columns: 1fr;
gap: 16px;
}
.game-card { margin: 0 4px; }
.game-cover { height: 160px; }
.game-info { padding: 14px; }
.game-actions {
flex-direction: column;
}
.btn {
width: 100%;
padding: 12px;
}
}
/* 小屏手机优化 */
@media (max-width: 480px) {
.stats {
grid-template-columns: 1fr;
}
.game-meta {
flex-direction: column;
align-items: flex-start;
gap: 6px;
}
}
/* 高分辨率显示器优化 */
@media (min-width: 1400px) {
.games-grid {
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
}
}

View File

@@ -1,63 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Epic Games 免费游戏 - 60s API 集合</title>
<meta name="description" content="Epic Games 免费游戏列表,数据源自 60s.viki.moe提供当前免费和即将免费的游戏信息。" />
<link rel="stylesheet" href="./css/style.css" />
</head>
<body>
<div class="container">
<header class="header">
<h1>
🎮 Epic Games 免费游戏
</h1>
</header>
<!-- 加载与错误状态 -->
<section id="loading" class="loading">
<div class="spinner"></div>
<p>正在加载游戏数据,请稍候…</p>
</section>
<section id="error" class="error" style="display: none;">
<p>获取数据失败,请稍后重试</p>
<button id="refresh-btn" class="btn" style="margin-top: 15px;">重新加载</button>
</section>
<!-- 内容区域 -->
<main id="content" style="display: none;" class="fade-in">
<!-- 统计信息 -->
<div class="stats">
<div class="stat-card">
<div class="stat-number" id="total-games">0</div>
<div class="stat-label">总游戏数</div>
</div>
<div class="stat-card">
<div class="stat-number" id="free-now">0</div>
<div class="stat-label">当前免费</div>
</div>
<div class="stat-card">
<div class="stat-number" id="upcoming">0</div>
<div class="stat-label">即将免费</div>
</div>
</div>
<!-- 游戏列表 -->
<div class="games-grid" id="games-grid">
<!-- 游戏卡片将通过 JavaScript 动态生成 -->
</div>
<!-- 刷新按钮 -->
<div style="text-align: center; margin-top: 30px;">
<button id="refresh-btn" class="btn btn-secondary">🔄 刷新数据</button>
</div>
</main>
</div>
<script src="./js/script.js"></script>
</body>
</html>

View File

@@ -1,266 +0,0 @@
// Epic Games 免费游戏 页面脚本
(function () {
'use strict';
const API = {
endpoints: [],
currentIndex: 0,
// 初始化API接口列表
async init() {
try {
const res = await fetch('./接口集合.json');
const endpoints = await res.json();
this.endpoints = endpoints.map(endpoint => `${endpoint}/v2/epic`);
} catch (e) {
// 如果无法加载接口集合,使用默认接口
this.endpoints = ['https://60s-api.viki.moe/v2/epic'];
}
},
// 获取当前接口URL
getCurrentUrl(encoding) {
if (this.endpoints.length === 0) return null;
const url = new URL(this.endpoints[this.currentIndex]);
if (encoding) url.searchParams.set('encoding', encoding);
return url.toString();
},
// 切换到下一个接口
switchToNext() {
this.currentIndex = (this.currentIndex + 1) % this.endpoints.length;
return this.currentIndex < this.endpoints.length;
},
// 重置到第一个接口
reset() {
this.currentIndex = 0;
}
};
// DOM 元素引用
const els = {
loading: null,
error: null,
container: null,
gamesGrid: null,
totalGames: null,
freeNow: null,
upcoming: null,
refreshBtn: null,
};
function initDom() {
els.loading = document.getElementById('loading');
els.error = document.getElementById('error');
els.container = document.getElementById('content');
els.gamesGrid = document.getElementById('games-grid');
els.totalGames = document.getElementById('total-games');
els.freeNow = document.getElementById('free-now');
els.upcoming = document.getElementById('upcoming');
els.refreshBtn = document.getElementById('refresh-btn');
}
function showLoading() {
els.loading.style.display = 'block';
els.error.style.display = 'none';
els.container.style.display = 'none';
}
function showError(msg) {
els.loading.style.display = 'none';
els.error.style.display = 'block';
els.container.style.display = 'none';
els.error.querySelector('p').textContent = msg || '获取数据失败,请稍后重试';
}
function showContent() {
els.loading.style.display = 'none';
els.error.style.display = 'none';
els.container.style.display = 'block';
}
function safeText(text) {
const div = document.createElement('div');
div.textContent = text == null ? '' : String(text);
return div.innerHTML;
}
function formatDate(dateStr) {
if (!dateStr) return '';
try {
const date = new Date(dateStr);
return date.toLocaleDateString('zh-CN', {
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit'
});
} catch (e) {
return dateStr;
}
}
async function fetchData(preferLocal = false) {
if (preferLocal) {
try {
const res = await fetch('./返回接口.json', { cache: 'no-store' });
const json = await res.json();
return json;
} catch (e) {
throw new Error('本地数据加载失败');
}
}
// 重置API索引到第一个接口
API.reset();
// 尝试所有API接口
for (let i = 0; i < API.endpoints.length; i++) {
try {
const url = API.getCurrentUrl();
console.log(`尝试接口 ${i + 1}/${API.endpoints.length}: ${url}`);
const res = await fetch(url, {
cache: 'no-store',
timeout: 10000 // 10秒超时
});
if (!res.ok) {
throw new Error(`HTTP ${res.status}: ${res.statusText}`);
}
const json = await res.json();
if (json && json.code === 200) {
console.log(`接口 ${i + 1} 请求成功`);
return json;
}
throw new Error(json && json.message ? json.message : '接口返回异常');
} catch (e) {
console.warn(`接口 ${i + 1} 失败:`, e.message);
// 如果不是最后一个接口,切换到下一个
if (i < API.endpoints.length - 1) {
API.switchToNext();
continue;
}
// 所有接口都失败了,尝试本地数据
console.warn('所有远程接口都失败,尝试本地数据');
try {
const res = await fetch('./返回接口.json', { cache: 'no-store' });
const json = await res.json();
return json;
} catch (e2) {
throw new Error('所有接口和本地数据都无法访问');
}
}
}
}
function createGameCard(game) {
const isFree = game.is_free_now;
const statusClass = isFree ? 'status-free' : 'status-upcoming';
const statusText = isFree ? '限时免费' : '即将免费';
return `
<div class="game-card fade-in">
<div class="status-badge ${statusClass}">${statusText}</div>
<img class="game-cover" src="${safeText(game.cover)}" alt="${safeText(game.title)} 封面" loading="lazy" />
<div class="game-info">
<h3 class="game-title">${safeText(game.title)}</h3>
<p class="game-description">${safeText(game.description)}</p>
<div class="game-meta">
<div class="game-price">
<span class="original-price">${safeText(game.original_price_desc)}</span>
<span class="free-price">免费</span>
</div>
<div class="game-seller">${safeText(game.seller)}</div>
</div>
<div class="game-dates">
<div class="free-period">
<span>开始:${formatDate(game.free_start)}</span>
<span>结束:${formatDate(game.free_end)}</span>
</div>
</div>
<div class="game-actions">
<a href="${safeText(game.link)}" target="_blank" class="btn">
${isFree ? '立即领取' : '查看详情'}
</a>
</div>
</div>
</div>
`;
}
function updateStats(games) {
const total = games.length;
const freeNow = games.filter(game => game.is_free_now).length;
const upcoming = total - freeNow;
els.totalGames.textContent = total;
els.freeNow.textContent = freeNow;
els.upcoming.textContent = upcoming;
}
function renderGames(games) {
if (!Array.isArray(games) || games.length === 0) {
els.gamesGrid.innerHTML = '<div style="grid-column: 1/-1; text-align: center; padding: 40px; color: #5a7c65;">暂无游戏数据</div>';
return;
}
// 按状态排序:免费的在前
const sortedGames = [...games].sort((a, b) => {
if (a.is_free_now && !b.is_free_now) return -1;
if (!a.is_free_now && b.is_free_now) return 1;
return 0;
});
const html = sortedGames.map(game => createGameCard(game)).join('');
els.gamesGrid.innerHTML = html;
updateStats(games);
}
function render(data) {
const games = data?.data || [];
renderGames(games);
showContent();
}
async function load() {
showLoading();
// 初始化API接口列表
await API.init();
try {
const data = await fetchData(false);
render(data);
} catch (e) {
console.error('数据获取失败:', e);
showError(e.message || '获取数据失败,请稍后重试');
}
}
function bindEvents() {
if (els.refreshBtn) {
els.refreshBtn.addEventListener('click', load);
}
// 快捷键 Ctrl+R 刷新(不拦截浏览器默认刷新)
document.addEventListener('keydown', (e) => {
if (e.ctrlKey && e.key === 'r' && !e.defaultPrevented) {
// 不阻止默认行为,让浏览器正常刷新
}
});
}
document.addEventListener('DOMContentLoaded', () => {
initDom();
bindEvents();
load();
});
})();

View File

@@ -1,7 +0,0 @@
[
"https://60s-cf.viki.moe",
"https://60s.viki.moe",
"https://60s.b23.run",
"https://60s.114128.xyz",
"https://60s-cf.114128.xyz"
]

View File

@@ -1,66 +0,0 @@
{
"code": 200,
"message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s反馈群 595941841",
"data": [
{
"id": "9aa227e2ba294bb1a95c95fde892eb31",
"title": "《Totally Reliable Delivery Service》 Standard Edition",
"cover": "https://cdn1.epicgames.com/52b90f9a982a404781b189f6a7903226/offer/EGS_TotallyReliableDeliveryService_WereFiveGames_S1-2560x1440-47e6e9562d62705a75ea7b7096d0b8dc.jpg",
"original_price": 52,
"original_price_desc": "¥52.00",
"description": "穿好护腰护具发动货车送货的时间到啦在一个高度互动的沙盒世界中与最多三位好友一起随意地完成送货。货物已试投这就是我们靠谱快递Totally Reliable Delivery Service的品质保证",
"seller": "Infogrames LLC",
"is_free_now": true,
"free_start": "2025/08/14 23:00:00",
"free_start_at": 1755183600000,
"free_end": "2025/08/21 23:00:00",
"free_end_at": 1755788400000,
"link": "https://store.epicgames.com/store/zh-CN/p/totally-reliable-delivery-service/home"
},
{
"id": "8ea3500dc38e4f429702bf889c172d3d",
"title": "Hidden Folks",
"cover": "https://cdn1.epicgames.com/spt-assets/7bfd56b0586348dcb139945d9e59f988/hidden-folks-1b7hh.png",
"original_price": 47,
"original_price_desc": "¥47.00",
"description": "Search for hidden folks in hand-drawn, interactive, miniature landscapes. Unfurl tent flaps, cut through bushes, slam doors, and poke some crocodiles! Rooooaaaarrrr!!!!!",
"seller": "Adriaan de Jongh",
"is_free_now": true,
"free_start": "2025/08/14 23:00:00",
"free_start_at": 1755183600000,
"free_end": "2025/08/21 23:00:00",
"free_end_at": 1755788400000,
"link": "https://store.epicgames.com/store/zh-CN/p/hidden-folks-239d16"
},
{
"id": "4cbb6c3704d240f19c3dd5f5cb2b0cb4",
"title": "Kamaeru",
"cover": "https://cdn1.epicgames.com/spt-assets/44313cfbb62b4df5801d0c8d541c2624/kamaeru-40asc.png",
"original_price": 62,
"original_price_desc": "¥62.00",
"description": "Foster a sanctuary for frogs and restore the biodiversity of the wetlands in Kamaeru, a cozy frog collecting game, where you take pictures of frogs, play mini-games and decorate your habitat. Hop right to it!",
"seller": "Armor Games Studios",
"is_free_now": false,
"free_start": "2025/08/21 23:00:00",
"free_start_at": 1755788400000,
"free_end": "2025/08/28 23:00:00",
"free_end_at": 1756393200000,
"link": "https://store.epicgames.com/store/zh-CN/p/kamaeru-0c301e"
},
{
"id": "0d9a533f0e684cc18620a8f408e8e72c",
"title": "Strange Horticulture",
"cover": "https://cdn1.epicgames.com/spt-assets/15e8e3eba65a4763a815d6eae1d763b2/strange-horticulture-offer-2wghv.png",
"original_price": 45,
"original_price_desc": "¥45.00",
"description": "款神秘学解谜游戏,你将扮演当地植物商店的店主,寻找并识别新的植物,悠闲撸猫,与女巫团体交谈,或加入异教。收集各种强大的植物,用它们来影响故事走向,揭开昂德米尔镇的黑暗谜团。",
"seller": "Iceberg Interactive",
"is_free_now": false,
"free_start": "2025/08/21 23:00:00",
"free_start_at": 1755788400000,
"free_end": "2025/08/28 23:00:00",
"free_end_at": 1756393200000,
"link": "https://store.epicgames.com/store/zh-CN/p/strange-horticulture-360e80"
}
]
}

View File

@@ -1,89 +0,0 @@
/* 玻璃拟态背景相关样式 */
body {
background: linear-gradient(135deg,
#667eea 0%,
#764ba2 25%,
#f093fb 50%,
#f5576c 75%,
#4facfe 100%
);
background-size: 400% 400%;
animation: gradientShift 20s ease infinite;
background-attachment: fixed;
min-height: 100vh;
position: relative;
}
@keyframes gradientShift {
0% { background-position: 0% 50%; }
25% { background-position: 100% 50%; }
50% { background-position: 100% 100%; }
75% { background-position: 0% 100%; }
100% { background-position: 0% 50%; }
}
/* 玻璃拟态装饰层 */
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background:
radial-gradient(circle at 20% 20%, rgba(255, 255, 255, 0.1) 0%, transparent 40%),
radial-gradient(circle at 80% 80%, rgba(255, 255, 255, 0.08) 0%, transparent 40%),
radial-gradient(circle at 40% 60%, rgba(255, 255, 255, 0.06) 0%, transparent 30%),
radial-gradient(circle at 60% 30%, rgba(255, 255, 255, 0.05) 0%, transparent 35%);
pointer-events: none;
z-index: -1;
animation: glassFloat 25s ease-in-out infinite alternate;
}
/* 毛玻璃气泡效果 */
body::after {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image:
radial-gradient(circle at 10% 20%, rgba(255, 255, 255, 0.3) 2px, transparent 2px),
radial-gradient(circle at 30% 40%, rgba(255, 255, 255, 0.25) 3px, transparent 3px),
radial-gradient(circle at 50% 60%, rgba(255, 255, 255, 0.2) 1.5px, transparent 1.5px),
radial-gradient(circle at 70% 80%, rgba(255, 255, 255, 0.3) 2.5px, transparent 2.5px),
radial-gradient(circle at 90% 10%, rgba(255, 255, 255, 0.25) 2px, transparent 2px),
radial-gradient(circle at 20% 90%, rgba(255, 255, 255, 0.2) 1px, transparent 1px);
background-size: 300px 300px, 250px 250px, 400px 400px, 200px 200px, 350px 350px, 150px 150px;
animation: bubbleFloat 30s linear infinite;
pointer-events: none;
z-index: -1;
opacity: 0.7;
}
@keyframes glassFloat {
0% {
transform: translateY(0px) rotate(0deg);
opacity: 0.7;
}
100% {
transform: translateY(-20px) rotate(2deg);
opacity: 0.9;
}
}
@keyframes bubbleFloat {
0%, 100% {
transform: translateX(0) translateY(0);
}
25% {
transform: translateX(-15px) translateY(-10px);
}
50% {
transform: translateX(10px) translateY(-20px);
}
75% {
transform: translateX(-5px) translateY(-15px);
}
}

View File

@@ -1,71 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>🌙 农历信息查询</title>
<link rel="stylesheet" href="css/background.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="container">
<header class="header">
<div class="header-icon">🏮</div>
<h1 class="title">🌙 农历信息查询 📅</h1>
<p class="subtitle">传统文化 · 时光转换 · 节气查询</p>
<div class="date-selector">
<div class="input-group">
<label for="dateInput" class="input-label">
<span class="label-icon">📅</span>
选择日期
</label>
<input type="date" id="dateInput" class="date-input" />
</div>
<button id="queryBtn" class="query-btn">
<span class="btn-icon">🔍</span>
查询农历
</button>
</div>
<div class="update-time">
<span class="time-icon"></span>
<span id="updateTime">等待查询...</span>
</div>
</header>
<div class="loading" id="loading" style="display: none;">
<div class="loading-content">
<div class="glass-spinner"></div>
<div class="loading-text">
<span class="loading-emoji">🔮</span>
<p>正在查询农历信息...</p>
<div class="loading-dots">
<span></span>
<span></span>
<span></span>
</div>
</div>
</div>
</div>
<div class="lunar-info" id="lunarInfo" style="display: none;">
<!-- 农历信息将动态生成 -->
</div>
<div class="error-message" id="errorMessage" style="display: none;">
<div class="error-content">
<div class="error-icon">😔</div>
<h3>查询失败了</h3>
<p>无法获取农历信息,请稍后重试</p>
<button onclick="queryLunarInfo()" class="retry-btn">
<span>🔄</span>
重新查询
</button>
</div>
</div>
<script src="js/script.js"></script>
</body>
</html>

View File

@@ -1,485 +0,0 @@
// API接口列表
const API_ENDPOINTS = [
"https://60s-cf.viki.moe",
"https://60s.viki.moe",
"https://60s.b23.run",
"https://60s.114128.xyz",
"https://60s-cf.114128.xyz"
];
// 当前使用的API索引
let currentApiIndex = 0;
// DOM元素
const loadingElement = document.getElementById('loading');
const lunarInfoElement = document.getElementById('lunarInfo');
const errorMessageElement = document.getElementById('errorMessage');
const updateTimeElement = document.getElementById('updateTime');
const dateInput = document.getElementById('dateInput');
const queryBtn = document.getElementById('queryBtn');
// 页面加载完成后初始化
document.addEventListener('DOMContentLoaded', function() {
initializePage();
});
// 初始化页面
function initializePage() {
// 设置默认日期为今天
const today = new Date();
const dateString = today.toISOString().split('T')[0];
dateInput.value = dateString;
// 绑定事件
queryBtn.addEventListener('click', queryLunarInfo);
dateInput.addEventListener('change', queryLunarInfo);
// 自动查询当天信息
queryLunarInfo();
}
// 查询农历信息
async function queryLunarInfo() {
const selectedDate = dateInput.value;
if (!selectedDate) {
showError('请选择查询日期');
return;
}
showLoading();
hideError();
hideLunarInfo();
try {
const data = await fetchLunarData(selectedDate);
displayLunarInfo(data.data);
updateQueryTime();
} catch (error) {
console.error('查询失败:', error);
showError('查询农历信息失败,请稍后重试');
}
hideLoading();
}
// 获取农历数据
async function fetchLunarData(date) {
for (let i = 0; i < API_ENDPOINTS.length; i++) {
const apiUrl = API_ENDPOINTS[currentApiIndex];
try {
const response = await fetch(`${apiUrl}/v2/lunar?date=${date}`, {
method: 'GET',
headers: {
'Accept': 'application/json',
},
timeout: 10000
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
const data = await response.json();
if (data.code === 200 && data.data) {
return data;
} else {
throw new Error('数据格式错误');
}
} catch (error) {
console.error(`API ${apiUrl} 请求失败:`, error);
currentApiIndex = (currentApiIndex + 1) % API_ENDPOINTS.length;
if (i === API_ENDPOINTS.length - 1) {
throw new Error('所有API接口都无法访问');
}
}
}
}
// 显示农历信息
function displayLunarInfo(lunarData) {
lunarInfoElement.innerHTML = `
<div class="info-card">
<div class="card-header">
<div class="card-icon">📅</div>
<div class="card-title">公历信息</div>
</div>
<div class="card-content">
<div class="info-item">
<div class="item-icon">🗓️</div>
<div class="item-label">公历日期</div>
<div class="item-value">${lunarData.solar.year}${String(lunarData.solar.month).padStart(2, '0')}${String(lunarData.solar.day).padStart(2, '0')}日</div>
</div>
<div class="info-item">
<div class="item-icon">🌍</div>
<div class="item-label">星期</div>
<div class="item-value">${lunarData.solar.week_desc}</div>
</div>
<div class="info-item">
<div class="item-icon"><3E></div>
<div class="item-label">季节</div>
<div class="item-value">${lunarData.solar.season_name_desc}</div>
</div>
<div class="info-item">
<div class="item-icon">⭐</div>
<div class="item-label">星座</div>
<div class="item-value">${lunarData.constellation.name}</div>
</div>
</div>
</div>
<div class="info-card">
<div class="card-header">
<div class="card-icon">🌙</div>
<div class="card-title">农历信息</div>
</div>
<div class="card-content">
<div class="info-item">
<div class="item-icon">🏮</div>
<div class="item-label">农历日期</div>
<div class="item-value">${lunarData.lunar.desc_short}</div>
</div>
<div class="info-item">
<div class="item-icon">🐲</div>
<div class="item-label">生肖年</div>
<div class="item-value">${lunarData.zodiac.year}年</div>
</div>
<div class="info-item">
<div class="item-icon">⚡</div>
<div class="item-label">天干地支</div>
<div class="item-value">${lunarData.sixty_cycle.year.name}</div>
</div>
<div class="info-item">
<div class="item-icon">🌙</div>
<div class="item-label">月相</div>
<div class="item-value">${lunarData.phase.name}</div>
</div>
</div>
</div>
<div class="info-card">
<div class="card-header">
<div class="card-icon">🌸</div>
<div class="card-title">节气节日</div>
</div>
<div class="card-content">
<div class="info-item">
<div class="item-icon">🍃</div>
<div class="item-label">当前节气</div>
<div class="item-value">${lunarData.term.stage ? lunarData.term.stage.name : '无节气'}</div>
</div>
<div class="info-item">
<div class="item-icon">🎊</div>
<div class="item-label">法定假日</div>
<div class="item-value">${lunarData.legal_holiday ? lunarData.legal_holiday.name : '无假日'}</div>
</div>
<div class="info-item">
<div class="item-icon"><3E></div>
<div class="item-label">传统节日</div>
<div class="item-value">${lunarData.festival.both_desc || '无特殊节日'}</div>
</div>
<div class="info-item">
<div class="item-icon">🔢</div>
<div class="item-label">一年第几天</div>
<div class="item-value">第${lunarData.stats.day_of_year}天</div>
</div>
</div>
</div>
<div class="info-card">
<div class="card-header">
<div class="card-icon">⏰</div>
<div class="card-title">时辰干支</div>
</div>
<div class="card-content">
<div class="info-item">
<div class="item-icon">🕐</div>
<div class="item-label">当前时辰</div>
<div class="item-value">${lunarData.lunar.hour_desc}</div>
</div>
<div class="info-item">
<div class="item-icon">⚡</div>
<div class="item-label">时辰干支</div>
<div class="item-value">${lunarData.sixty_cycle.hour.name}</div>
</div>
<div class="info-item">
<div class="item-icon">🐓</div>
<div class="item-label">时辰生肖</div>
<div class="item-value">${lunarData.zodiac.hour}</div>
</div>
<div class="info-item">
<div class="item-icon">🎵</div>
<div class="item-label">纳音</div>
<div class="item-value">${lunarData.nayin.hour}</div>
</div>
</div>
</div>
<div class="info-card">
<div class="card-header">
<div class="card-icon">🔮</div>
<div class="card-title">黄历宜忌</div>
</div>
<div class="card-content">
<div class="info-item">
<div class="item-icon">✅</div>
<div class="item-label">宜</div>
<div class="item-value">${formatTabooText(lunarData.taboo.day.recommends)}</div>
</div>
<div class="info-item">
<div class="item-icon">❌</div>
<div class="item-label">忌</div>
<div class="item-value">${formatTabooText(lunarData.taboo.day.avoids)}</div>
</div>
<div class="info-item">
<div class="item-icon">🕐</div>
<div class="item-label">时辰宜</div>
<div class="item-value">${formatTabooText(lunarData.taboo.hour.recommends)}</div>
</div>
<div class="info-item">
<div class="item-icon">🚫</div>
<div class="item-label">时辰忌</div>
<div class="item-value">${formatTabooText(lunarData.taboo.hour.avoids)}</div>
</div>
</div>
</div>
<div class="info-card">
<div class="card-header">
<div class="card-icon">🌟</div>
<div class="card-title">运势财运</div>
</div>
<div class="card-content">
<div class="info-item">
<div class="item-icon">🎯</div>
<div class="item-label">今日运势</div>
<div class="item-value">${lunarData.fortune.today_luck}</div>
</div>
<div class="info-item">
<div class="item-icon">💼</div>
<div class="item-label">事业运</div>
<div class="item-value">${lunarData.fortune.career}</div>
</div>
<div class="info-item">
<div class="item-icon">💰</div>
<div class="item-label">财运</div>
<div class="item-value">${lunarData.fortune.money}</div>
</div>
<div class="info-item">
<div class="item-icon">💕</div>
<div class="item-label">感情运</div>
<div class="item-value">${lunarData.fortune.love}</div>
</div>
</div>
</div>
<div class="info-card">
<div class="card-header">
<div class="card-icon">📊</div>
<div class="card-title">年度统计</div>
</div>
<div class="card-content">
<div class="info-item">
<div class="item-icon">📈</div>
<div class="item-label">年度进度</div>
<div class="item-value">${lunarData.stats.percents_formatted.year}</div>
</div>
<div class="info-item">
<div class="item-icon">📅</div>
<div class="item-label">本月进度</div>
<div class="item-value">${lunarData.stats.percents_formatted.month}</div>
</div>
<div class="info-item">
<div class="item-icon">🗓️</div>
<div class="item-label">本周第几天</div>
<div class="item-value">第${lunarData.stats.week_of_month}周</div>
</div>
<div class="info-item">
<div class="item-icon">⏰</div>
<div class="item-label">今日进度</div>
<div class="item-value">${lunarData.stats.percents_formatted.day}</div>
</div>
</div>
</div>
${generateHourlyTaboo(lunarData.taboo.hours)}
`;
showLunarInfo();
}
// 格式化宜忌文本
function formatTabooText(text) {
if (!text) return '无';
return text.replace(/\./g, '、');
}
// 生成十二时辰宜忌
function generateHourlyTaboo(hours) {
if (!hours || hours.length === 0) return '';
const hourCards = hours.map(hour => `
<div class="hour-item">
<div class="hour-name">${hour.hour}</div>
<div class="hour-content">
<div class="hour-recommends">
<span class="hour-label">宜:</span>
<span class="hour-text">${formatTabooText(hour.recommends) || '无'}</span>
</div>
<div class="hour-avoids">
<span class="hour-label">忌:</span>
<span class="hour-text">${formatTabooText(hour.avoids) || '无'}</span>
</div>
</div>
</div>
`).join('');
return `
<div class="info-card hours-card">
<div class="card-header">
<div class="card-icon">⏰</div>
<div class="card-title">十二时辰宜忌</div>
</div>
<div class="card-content">
<div class="hours-grid">
${hourCards}
</div>
</div>
</div>
`;
}
// 更新查询时间
function updateQueryTime() {
const now = new Date();
const timeStr = now.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
});
updateTimeElement.textContent = `查询时间: ${timeStr}`;
// 添加成功提示
showSuccessMessage('🌙 农历信息已更新');
}
// 显示成功消息
function showSuccessMessage(message) {
// 移除之前的提示
const existingToast = document.querySelector('.success-toast');
if (existingToast) {
existingToast.remove();
}
const toast = document.createElement('div');
toast.className = 'success-toast';
toast.textContent = message;
toast.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
background: rgba(255, 255, 255, 0.2);
backdrop-filter: blur(15px);
-webkit-backdrop-filter: blur(15px);
color: rgba(255, 255, 255, 0.95);
padding: 12px 20px;
border-radius: 25px;
border: 1px solid rgba(255, 255, 255, 0.3);
box-shadow: 0 8px 32px rgba(31, 38, 135, 0.2);
z-index: 1000;
font-weight: 600;
font-size: 0.9em;
animation: glassToastSlide 0.5s ease-out;
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
`;
document.body.appendChild(toast);
// 3秒后自动移除
setTimeout(() => {
toast.style.animation = 'glassToastSlideOut 0.5s ease-in forwards';
setTimeout(() => toast.remove(), 500);
}, 3000);
}
// 显示加载状态
function showLoading() {
loadingElement.style.display = 'block';
}
// 隐藏加载状态
function hideLoading() {
loadingElement.style.display = 'none';
}
// 显示农历信息
function showLunarInfo() {
lunarInfoElement.style.display = 'block';
}
// 隐藏农历信息
function hideLunarInfo() {
lunarInfoElement.style.display = 'none';
}
// 显示错误信息
function showError(message = '查询失败,请稍后重试') {
errorMessageElement.style.display = 'block';
const errorContent = errorMessageElement.querySelector('.error-content p');
if (errorContent) {
errorContent.textContent = message;
}
}
// 隐藏错误信息
function hideError() {
errorMessageElement.style.display = 'none';
}
// 添加CSS动画到页面
if (!document.querySelector('#toast-styles')) {
const style = document.createElement('style');
style.id = 'toast-styles';
style.textContent = `
@keyframes glassToastSlide {
from {
opacity: 0;
transform: translateX(100px) scale(0.8);
}
to {
opacity: 1;
transform: translateX(0) scale(1);
}
}
@keyframes glassToastSlideOut {
from {
opacity: 1;
transform: translateX(0) scale(1);
}
to {
opacity: 0;
transform: translateX(100px) scale(0.8);
}
}
`;
document.head.appendChild(style);
}
// 键盘快捷键支持
document.addEventListener('keydown', function(e) {
if (e.key === 'Enter') {
e.preventDefault();
queryLunarInfo();
}
if (e.key === 'r' && (e.ctrlKey || e.metaKey)) {
e.preventDefault();
queryLunarInfo();
}
});

View File

@@ -1,7 +0,0 @@
[
"https://60s-cf.viki.moe",
"https://60s.viki.moe",
"https://60s.b23.run",
"https://60s.114128.xyz",
"https://60s-cf.114128.xyz"
]

View File

@@ -1,647 +0,0 @@
{
"code": 200,
"message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s反馈群 595941841",
"data": {
"solar": {
"year": 2025,
"month": 9,
"day": 1,
"hour": 17,
"minute": 58,
"second": 47,
"full": "2025-09-01",
"full_with_time": "2025-09-01 17:58:47",
"week": 1,
"week_desc": "星期一",
"week_desc_short": "一",
"season": 3,
"season_desc": "三季度",
"season_desc_short": "三",
"season_name": "秋",
"season_name_desc": "秋天",
"is_leap_year": false
},
"lunar": {
"year": "乙巳",
"month": "七",
"day": "初十",
"hour": "酉",
"full_with_hour": "农历乙巳年七月初十酉时",
"desc_short": "农历乙巳年七月初十",
"year_desc": "农历乙巳年",
"month_desc": "七月",
"day_desc": "初十",
"hour_desc": "酉时",
"is_leap_month": false
},
"stats": {
"day_of_year": 244,
"week_of_year": 36,
"week_of_month": 1,
"percents": {
"year": 0.665753424657534,
"month": 0.0333333333333333,
"week": 0.142857142857143,
"day": 0.749161909722222
},
"percents_formatted": {
"year": "66.58%",
"month": "3.33%",
"week": "14.29%",
"day": "74.92%"
}
},
"term": {
"today": null,
"stage": {
"name": "处暑",
"position": 10,
"is_jie": false,
"is_qi": true
}
},
"zodiac": {
"year": "蛇",
"month": "鸡",
"day": "鸡",
"hour": "鸡"
},
"sixty_cycle": {
"year": {
"heaven_stem": "乙",
"earth_branch": "巳",
"name": "乙巳年",
"name_short": "乙巳"
},
"month": {
"heaven_stem": "乙",
"earth_branch": "酉",
"name": "乙酉月",
"name_short": "乙酉"
},
"day": {
"heaven_stem": "癸",
"earth_branch": "酉",
"name": "癸酉日",
"name_short": "癸酉"
},
"hour": {
"heaven_stem": "辛",
"earth_branch": "酉",
"name": "辛酉时",
"name_short": "辛酉"
}
},
"legal_holiday": null,
"festival": {
"solar": null,
"lunar": null,
"both_desc": null
},
"phase": {
"name": "宵月",
"position": 10
},
"constellation": {
"name": "处女座",
"name_short": "处女"
},
"taboo": {
"day": {
"recommends": "解除.祭祀.祈福.求嗣.修造.动土.竖柱.上梁.安床.纳畜.盖屋.合脊.起基.入殓.破土.安葬",
"avoids": "出火.嫁娶.开光.进人口.出行.词讼.开市.入宅.移徙.赴任"
},
"hour": {
"hour": "酉时",
"hour_short": "酉",
"avoids": "乘船.造桥",
"recommends": "嫁娶.出行.移徙.入宅.开市.赴任.祈福.安床.开仓.盖屋.修造.求财"
},
"hours": [
{
"hour": "酉时",
"hour_short": "酉",
"recommends": "嫁娶.出行.移徙.入宅.开市.赴任.祈福.安床.开仓.盖屋.修造.求财",
"avoids": "乘船.造桥"
},
{
"hour": "戌时",
"hour_short": "戌",
"recommends": "嫁娶.移徙.安葬.进人口.求财",
"avoids": "出行.赴任.祈福.祭祀.开光.斋醮"
},
{
"hour": "亥时",
"hour_short": "亥",
"recommends": "嫁娶.移徙.交易.入宅.开市.安葬.求嗣.求财",
"avoids": "出行.赴任.动土.祈福.祭祀.修造.开光.斋醮"
},
{
"hour": "子时",
"hour_short": "子",
"recommends": "嫁娶.交易.入宅.开市.祈福.安葬.求嗣.求财",
"avoids": "出行.移徙.赴任.词讼.修造"
},
{
"hour": "丑时",
"hour_short": "丑",
"recommends": "嫁娶.祈福.安葬.祭祀.酬神.求财",
"avoids": "出行.赴任.动土.修造"
},
{
"hour": "寅时",
"hour_short": "寅",
"recommends": "嫁娶.出行.交易.开市.赴任.祈福.安床.祭祀.求嗣.求财",
"avoids": "盖屋.入殓.上梁"
},
{
"hour": "卯时",
"hour_short": "卯",
"recommends": "嫁娶.交易.入宅.开市.祈福.安床.安葬.求嗣.求财",
"avoids": "出行.赴任.修造"
},
{
"hour": "辰时",
"hour_short": "辰",
"recommends": "",
"avoids": "诸事不宜"
},
{
"hour": "巳时",
"hour_short": "巳",
"recommends": "嫁娶.出行.移徙.入宅.开市.祈福.安床.盖屋.祭祀.作灶",
"avoids": "安葬.修造.开光"
},
{
"hour": "午时",
"hour_short": "午",
"recommends": "嫁娶.出行.交易.开市.祈福.安床.求嗣.求财",
"avoids": "赴任.动土.词讼.修造"
},
{
"hour": "未时",
"hour_short": "未",
"recommends": "嫁娶.入宅.祈福.安葬.祭祀.修造.酬神.求财",
"avoids": "出行.赴任"
},
{
"hour": "申时",
"hour_short": "申",
"recommends": "嫁娶.出行.开市.赴任.安葬.求财",
"avoids": "祈福.祭祀.酬神.斋醮"
}
]
},
"julian_day": 2460919.5,
"nayin": {
"year": "覆灯火",
"month": "泉中水",
"day": "剑锋金",
"hour": "石榴木"
},
"baizi": {
"year_baizi": "性格温和,为人正直诚信。",
"day_baizi": "性格温和,为人正直诚信。"
},
"fortune": {
"today_luck": "今日学习运好,适合进修",
"career": "领导能力突出,升职有望",
"money": "偏财运不错,可小试投资",
"love": "感情需要沟通,避免误会"
},
"constants": {
"legal_holiday_list": [
{
"name": "元旦节",
"date": "2025-01-01",
"start": "2025-01-01",
"end": "2025-01-01"
},
{
"name": "春节",
"date": "2025-01-29",
"start": "2025-01-26",
"end": "2025-02-08"
},
{
"name": "清明节",
"date": "2025-04-04",
"start": "2025-04-04",
"end": "2025-04-06"
},
{
"name": "劳动节",
"date": "2025-05-01",
"start": "2025-04-27",
"end": "2025-05-05"
},
{
"name": "端午节",
"date": "2025-05-31",
"start": "2025-05-31",
"end": "2025-06-02"
},
{
"name": "国庆中秋",
"date": "2025-10-01",
"start": "2025-09-28",
"end": "2025-10-11"
}
],
"phase_list": [
{
"name": "朔月",
"lunar_day": 1
},
{
"name": "既朔月",
"lunar_day": 2
},
{
"name": "蛾眉新月",
"lunar_day": 3
},
{
"name": "蛾眉新月",
"lunar_day": 4
},
{
"name": "蛾眉月",
"lunar_day": 5
},
{
"name": "夕月",
"lunar_day": 6
},
{
"name": "上弦月",
"lunar_day": 7
},
{
"name": "上弦月",
"lunar_day": 8
},
{
"name": "九夜月",
"lunar_day": 9
},
{
"name": "宵月",
"lunar_day": 10
},
{
"name": "宵月",
"lunar_day": 11
},
{
"name": "宵月",
"lunar_day": 12
},
{
"name": "渐盈凸月",
"lunar_day": 13
},
{
"name": "小望月",
"lunar_day": 14
},
{
"name": "望月",
"lunar_day": 15
},
{
"name": "既望月",
"lunar_day": 16
},
{
"name": "立待月",
"lunar_day": 17
},
{
"name": "居待月",
"lunar_day": 18
},
{
"name": "寝待月",
"lunar_day": 19
},
{
"name": "更待月",
"lunar_day": 20
},
{
"name": "渐亏凸月",
"lunar_day": 21
},
{
"name": "下弦月",
"lunar_day": 22
},
{
"name": "下弦月",
"lunar_day": 23
},
{
"name": "有明月",
"lunar_day": 24
},
{
"name": "有明月",
"lunar_day": 25
},
{
"name": "蛾眉残月",
"lunar_day": 26
},
{
"name": "蛾眉残月",
"lunar_day": 27
},
{
"name": "残月",
"lunar_day": 28
},
{
"name": "晓月",
"lunar_day": 29
},
{
"name": "晦月",
"lunar_day": 30
}
],
"zodiac_list": [
"鼠",
"牛",
"虎",
"兔",
"龙",
"蛇",
"马",
"羊",
"猴",
"鸡",
"狗",
"猪"
],
"constellation_list": [
{
"name": "白羊",
"desc": "白羊座",
"start": "3月21日",
"end": "4月19日",
"range": "3月21日~4月19日",
"start_month": 3,
"start_day": 21,
"end_month": 4,
"end_day": 19
},
{
"name": "金牛",
"desc": "金牛座",
"start": "4月20日",
"end": "5月20日",
"range": "4月20日~5月20日",
"start_month": 4,
"start_day": 20,
"end_month": 5,
"end_day": 20
},
{
"name": "双子",
"desc": "双子座",
"start": "5月21日",
"end": "6月21日",
"range": "5月21日~6月21日",
"start_month": 5,
"start_day": 21,
"end_month": 6,
"end_day": 21
},
{
"name": "巨蟹",
"desc": "巨蟹座",
"start": "6月22日",
"end": "7月22日",
"range": "6月22日~7月22日",
"start_month": 6,
"start_day": 22,
"end_month": 7,
"end_day": 22
},
{
"name": "狮子",
"desc": "狮子座",
"start": "7月23日",
"end": "8月22日",
"range": "7月23日~8月22日",
"start_month": 7,
"start_day": 23,
"end_month": 8,
"end_day": 22
},
{
"name": "处女",
"desc": "处女座",
"start": "8月23日",
"end": "9月22日",
"range": "8月23日~9月22日",
"start_month": 8,
"start_day": 23,
"end_month": 9,
"end_day": 22
},
{
"name": "天秤",
"desc": "天秤座",
"start": "9月23日",
"end": "10月23日",
"range": "9月23日~10月23日",
"start_month": 9,
"start_day": 23,
"end_month": 10,
"end_day": 23
},
{
"name": "天蝎",
"desc": "天蝎座",
"start": "10月24日",
"end": "11月22日",
"range": "10月24日~11月22日",
"start_month": 10,
"start_day": 24,
"end_month": 11,
"end_day": 22
},
{
"name": "射手",
"desc": "射手座",
"start": "11月23日",
"end": "12月21日",
"range": "11月23日~12月21日",
"start_month": 11,
"start_day": 23,
"end_month": 12,
"end_day": 21
},
{
"name": "摩羯",
"desc": "摩羯座",
"start": "12月22日",
"end": "1月19日",
"range": "12月22日~1月19日",
"start_month": 12,
"start_day": 22,
"end_month": 1,
"end_day": 19
},
{
"name": "水瓶",
"desc": "水瓶座",
"start": "1月20日",
"end": "2月18日",
"range": "1月20日~2月18日",
"start_month": 1,
"start_day": 20,
"end_month": 2,
"end_day": 18
},
{
"name": "双鱼",
"desc": "双鱼座",
"start": "2月19日",
"end": "3月20日",
"range": "2月19日~3月20日",
"start_month": 2,
"start_day": 19,
"end_month": 3,
"end_day": 20
}
],
"heaven_stems": [
"甲",
"乙",
"丙",
"丁",
"戊",
"己",
"庚",
"辛",
"壬",
"癸"
],
"earth_branches": [
"子",
"丑",
"寅",
"卯",
"辰",
"巳",
"午",
"未",
"申",
"酉",
"戌",
"亥"
],
"solar_terms": [
{
"name": "立春",
"desc": "春季开始"
},
{
"name": "雨水",
"desc": "降雨增多"
},
{
"name": "惊蛰",
"desc": "春雷乍响"
},
{
"name": "春分",
"desc": "昼夜等长"
},
{
"name": "清明",
"desc": "天清地明"
},
{
"name": "谷雨",
"desc": "雨生百谷"
},
{
"name": "立夏",
"desc": "夏季开始"
},
{
"name": "小满",
"desc": "麦粒渐满"
},
{
"name": "芒种",
"desc": "麦类收割"
},
{
"name": "夏至",
"desc": "白昼最长"
},
{
"name": "小暑",
"desc": "天气渐热"
},
{
"name": "大暑",
"desc": "一年最热"
},
{
"name": "立秋",
"desc": "秋季开始"
},
{
"name": "处暑",
"desc": "暑热结束"
},
{
"name": "白露",
"desc": "露水增多"
},
{
"name": "秋分",
"desc": "昼夜等长"
},
{
"name": "寒露",
"desc": "露水渐凉"
},
{
"name": "霜降",
"desc": "开始降霜"
},
{
"name": "立冬",
"desc": "冬季开始"
},
{
"name": "小雪",
"desc": "开始降雪"
},
{
"name": "大雪",
"desc": "降雪增多"
},
{
"name": "冬至",
"desc": "白昼最短"
},
{
"name": "小寒",
"desc": "天气渐冷"
},
{
"name": "大寒",
"desc": "一年最冷"
}
]
}
}
}

View File

@@ -1,145 +0,0 @@
/* 背景样式文件 */
body {
background: linear-gradient(135deg, #e8f5e8 0%, #d4f1d4 25%, #c8ecc8 50%, #b8e6b8 75%, #a8d5ba 100%);
background-attachment: fixed;
background-size: 400% 400%;
animation: gradientShift 15s ease infinite;
position: relative;
overflow-x: hidden;
}
/* 背景渐变动画 */
@keyframes gradientShift {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
/* 背景装饰元素 */
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image:
radial-gradient(circle at 20% 80%, rgba(168, 213, 186, 0.1) 0%, transparent 50%),
radial-gradient(circle at 80% 20%, rgba(107, 183, 123, 0.1) 0%, transparent 50%),
radial-gradient(circle at 40% 40%, rgba(200, 236, 200, 0.1) 0%, transparent 50%);
pointer-events: none;
z-index: -1;
}
/* 浮动装饰圆点 */
body::after {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image:
radial-gradient(2px 2px at 20px 30px, rgba(168, 213, 186, 0.3), transparent),
radial-gradient(2px 2px at 40px 70px, rgba(107, 183, 123, 0.2), transparent),
radial-gradient(1px 1px at 90px 40px, rgba(200, 236, 200, 0.4), transparent),
radial-gradient(1px 1px at 130px 80px, rgba(168, 213, 186, 0.2), transparent),
radial-gradient(2px 2px at 160px 30px, rgba(107, 183, 123, 0.3), transparent);
background-repeat: repeat;
background-size: 200px 100px;
animation: float 20s linear infinite;
pointer-events: none;
z-index: -1;
}
@keyframes float {
0% {
transform: translateY(0px);
}
50% {
transform: translateY(-10px);
}
100% {
transform: translateY(0px);
}
}
/* 云朵装饰效果 */
.container::before {
content: '';
position: absolute;
top: -50px;
right: -50px;
width: 200px;
height: 100px;
background: rgba(255, 255, 255, 0.1);
border-radius: 50px;
box-shadow:
-30px 20px 0 rgba(255, 255, 255, 0.08),
30px 40px 0 rgba(255, 255, 255, 0.06);
animation: cloudFloat 25s ease-in-out infinite;
pointer-events: none;
z-index: -1;
}
.container::after {
content: '';
position: absolute;
bottom: -30px;
left: -30px;
width: 150px;
height: 80px;
background: rgba(255, 255, 255, 0.08);
border-radius: 40px;
box-shadow:
20px 15px 0 rgba(255, 255, 255, 0.06),
-20px 25px 0 rgba(255, 255, 255, 0.04);
animation: cloudFloat 30s ease-in-out infinite reverse;
pointer-events: none;
z-index: -1;
}
@keyframes cloudFloat {
0%, 100% {
transform: translateX(0px) translateY(0px);
}
25% {
transform: translateX(20px) translateY(-10px);
}
50% {
transform: translateX(-10px) translateY(-20px);
}
75% {
transform: translateX(15px) translateY(-5px);
}
}
/* 响应式背景调整 */
@media (max-width: 768px) {
body::after {
background-size: 150px 75px;
}
.container::before,
.container::after {
display: none;
}
}
@media (max-width: 480px) {
body {
background: linear-gradient(135deg, #e8f5e8 0%, #d4f1d4 50%, #a8d5ba 100%);
animation: none;
}
body::before,
body::after {
display: none;
}
}

View File

@@ -1,409 +0,0 @@
/* 基础样式重置 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Microsoft YaHei', Arial, sans-serif;
line-height: 1.6;
color: #333;
min-height: 100vh;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
/* 头部样式 */
.header {
text-align: center;
margin-bottom: 30px;
}
.header h1 {
color: #2d5a3d;
font-size: 2.5rem;
font-weight: 300;
margin-bottom: 10px;
}
/* 搜索区域 */
.search-section {
margin-bottom: 30px;
}
.search-box {
display: flex;
justify-content: center;
gap: 10px;
max-width: 500px;
margin: 0 auto;
}
#cityInput {
flex: 1;
padding: 12px 16px;
border: 2px solid #a8d5ba;
border-radius: 25px;
font-size: 16px;
outline: none;
transition: all 0.3s ease;
background: rgba(255, 255, 255, 0.9);
}
#cityInput:focus {
border-color: #6bb77b;
box-shadow: 0 0 10px rgba(107, 183, 123, 0.3);
}
#searchBtn {
padding: 12px 24px;
background: linear-gradient(135deg, #6bb77b, #5a9f6a);
color: white;
border: none;
border-radius: 25px;
font-size: 16px;
cursor: pointer;
transition: all 0.3s ease;
white-space: nowrap;
}
#searchBtn:hover {
background: linear-gradient(135deg, #5a9f6a, #4a8759);
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(107, 183, 123, 0.4);
}
/* 加载动画 */
.loading {
text-align: center;
padding: 40px;
}
.spinner {
width: 40px;
height: 40px;
border: 4px solid #e8f5e8;
border-top: 4px solid #6bb77b;
border-radius: 50%;
animation: spin 1s linear infinite;
margin: 0 auto 20px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* 天气容器 */
.weather-container {
background: rgba(255, 255, 255, 0.95);
border-radius: 20px;
padding: 30px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
backdrop-filter: blur(10px);
border: 1px solid rgba(168, 213, 186, 0.3);
}
/* 位置信息 */
.location-info {
text-align: center;
margin-bottom: 30px;
padding-bottom: 20px;
border-bottom: 2px solid #e8f5e8;
}
.location-info h2 {
color: #2d5a3d;
font-size: 2rem;
margin-bottom: 5px;
}
.location-info p {
color: #666;
font-size: 14px;
}
/* 当前天气 */
.current-weather {
margin-bottom: 30px;
}
.weather-main {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 25px;
}
.temperature {
font-size: 4rem;
font-weight: 300;
color: #2d5a3d;
}
.unit {
font-size: 2rem;
color: #6bb77b;
}
.weather-desc p:first-child {
font-size: 1.5rem;
color: #2d5a3d;
margin-bottom: 5px;
}
.weather-desc p:last-child {
color: #666;
font-size: 14px;
}
/* 天气详情 */
.weather-details {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 15px;
}
.detail-item {
background: rgba(168, 213, 186, 0.1);
padding: 15px;
border-radius: 12px;
text-align: center;
border: 1px solid rgba(168, 213, 186, 0.2);
}
.detail-item .label {
display: block;
color: #666;
font-size: 12px;
margin-bottom: 5px;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.detail-item span:last-child {
color: #2d5a3d;
font-weight: 600;
font-size: 16px;
}
/* 生活指数 */
.life-index {
margin-top: 30px;
}
.life-index h3 {
color: #2d5a3d;
font-size: 1.5rem;
margin-bottom: 20px;
text-align: center;
}
.index-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 20px;
}
.index-item {
display: flex;
align-items: center;
background: rgba(168, 213, 186, 0.05);
padding: 20px;
border-radius: 15px;
border: 1px solid rgba(168, 213, 186, 0.2);
transition: all 0.3s ease;
}
.index-item:hover {
background: rgba(168, 213, 186, 0.1);
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(168, 213, 186, 0.2);
}
.index-icon {
font-size: 2rem;
margin-right: 15px;
width: 50px;
text-align: center;
}
.index-content h4 {
color: #2d5a3d;
font-size: 16px;
margin-bottom: 5px;
}
.index-content p {
color: #6bb77b;
font-weight: 600;
margin-bottom: 3px;
}
.index-content span {
color: #666;
font-size: 13px;
line-height: 1.4;
}
/* 更新时间 */
.update-time {
text-align: center;
margin-top: 30px;
padding-top: 20px;
border-top: 1px solid #e8f5e8;
color: #666;
font-size: 14px;
}
/* 错误信息 */
.error-message {
text-align: center;
padding: 40px;
background: rgba(255, 107, 107, 0.1);
border-radius: 15px;
border: 1px solid rgba(255, 107, 107, 0.2);
color: #d63031;
}
/* 平板端适配 (768px - 1024px) */
@media (min-width: 768px) and (max-width: 1024px) {
.container {
padding: 25px;
}
.header h1 {
font-size: 2.2rem;
}
.temperature {
font-size: 3.5rem;
}
.weather-details {
grid-template-columns: repeat(3, 1fr);
}
.index-grid {
grid-template-columns: repeat(2, 1fr);
}
}
/* 电脑端适配 (1024px+) */
@media (min-width: 1024px) {
.container {
padding: 40px;
}
.weather-container {
padding: 40px;
}
.weather-main {
justify-content: space-around;
}
.weather-details {
grid-template-columns: repeat(6, 1fr);
}
.index-grid {
grid-template-columns: repeat(3, 1fr);
}
.search-box {
max-width: 600px;
}
}
/* 手机端适配 (768px以下) */
@media (max-width: 767px) {
.container {
padding: 15px;
}
.header h1 {
font-size: 2rem;
}
.search-box {
flex-direction: column;
gap: 15px;
}
#searchBtn {
padding: 14px 24px;
}
.weather-container {
padding: 20px;
margin: 0 -5px;
}
.weather-main {
flex-direction: column;
text-align: center;
gap: 20px;
}
.temperature {
font-size: 3rem;
}
.weather-details {
grid-template-columns: repeat(2, 1fr);
gap: 10px;
}
.detail-item {
padding: 12px;
}
.index-grid {
grid-template-columns: 1fr;
gap: 15px;
}
.index-item {
padding: 15px;
}
.index-icon {
font-size: 1.5rem;
width: 40px;
margin-right: 12px;
}
}
/* 超小屏幕适配 (480px以下) */
@media (max-width: 480px) {
.container {
padding: 10px;
}
.header h1 {
font-size: 1.8rem;
}
.weather-container {
padding: 15px;
border-radius: 15px;
}
.temperature {
font-size: 2.5rem;
}
.weather-details {
grid-template-columns: 1fr;
}
.detail-item {
padding: 10px;
}
}

View File

@@ -1,140 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>实时天气查询</title>
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="css/background.css">
</head>
<body>
<div class="container">
<header class="header">
<h1>实时天气查询</h1>
</header>
<div class="search-section">
<div class="search-box">
<input type="text" id="cityInput" placeholder="请输入城市名称(如:北京)" value="北京">
<button id="searchBtn">查询天气</button>
</div>
</div>
<div class="loading" id="loading" style="display: none;">
<div class="spinner"></div>
<p>正在获取天气信息...</p>
</div>
<div class="weather-container" id="weatherContainer" style="display: none;">
<div class="location-info">
<h2 id="locationName"></h2>
<p id="locationDetail"></p>
</div>
<div class="current-weather">
<div class="weather-main">
<div class="temperature">
<span id="temperature"></span>
<span class="unit">°C</span>
</div>
<div class="weather-desc">
<p id="weatherCondition"></p>
<p id="feelsLike"></p>
</div>
</div>
<div class="weather-details">
<div class="detail-item">
<span class="label">湿度</span>
<span id="humidity"></span>
</div>
<div class="detail-item">
<span class="label">风向</span>
<span id="windDirection"></span>
</div>
<div class="detail-item">
<span class="label">风力</span>
<span id="windStrength"></span>
</div>
<div class="detail-item">
<span class="label">气压</span>
<span id="pressure"></span>
</div>
<div class="detail-item">
<span class="label">能见度</span>
<span id="visibility"></span>
</div>
<div class="detail-item">
<span class="label">空气质量</span>
<span id="aqi"></span>
</div>
</div>
</div>
<div class="life-index">
<h3>生活指数</h3>
<div class="index-grid">
<div class="index-item">
<div class="index-icon comfort">🌡️</div>
<div class="index-content">
<h4>舒适度</h4>
<p id="comfortLevel"></p>
<span id="comfortDesc"></span>
</div>
</div>
<div class="index-item">
<div class="index-icon clothing">👕</div>
<div class="index-content">
<h4>穿衣指数</h4>
<p id="clothingLevel"></p>
<span id="clothingDesc"></span>
</div>
</div>
<div class="index-item">
<div class="index-icon umbrella">☂️</div>
<div class="index-content">
<h4>雨伞指数</h4>
<p id="umbrellaLevel"></p>
<span id="umbrellaDesc"></span>
</div>
</div>
<div class="index-item">
<div class="index-icon uv">☀️</div>
<div class="index-content">
<h4>紫外线</h4>
<p id="uvLevel"></p>
<span id="uvDesc"></span>
</div>
</div>
<div class="index-item">
<div class="index-icon travel">🚗</div>
<div class="index-content">
<h4>出行指数</h4>
<p id="travelLevel"></p>
<span id="travelDesc"></span>
</div>
</div>
<div class="index-item">
<div class="index-icon sport">🏃</div>
<div class="index-content">
<h4>运动指数</h4>
<p id="sportLevel"></p>
<span id="sportDesc"></span>
</div>
</div>
</div>
</div>
<div class="update-time">
<p>更新时间:<span id="updateTime"></span></p>
</div>
</div>
<div class="error-message" id="errorMessage" style="display: none;">
<p>获取天气信息失败,请稍后重试</p>
</div>
</div>
<script src="js/script.js"></script>
</body>
</html>

View File

@@ -1,252 +0,0 @@
// 天气查询应用
class WeatherApp {
constructor() {
this.apiEndpoints = [
'https://60s-cf.viki.moe',
'https://60s.viki.moe',
'https://60s.b23.run',
'https://60s.114128.xyz',
'https://60s-cf.114128.xyz'
];
this.currentEndpointIndex = 0;
this.init();
}
init() {
this.bindEvents();
// 页面加载时自动查询北京天气
this.searchWeather('北京');
}
bindEvents() {
const searchBtn = document.getElementById('searchBtn');
const cityInput = document.getElementById('cityInput');
searchBtn.addEventListener('click', () => {
const city = cityInput.value.trim();
if (city) {
this.searchWeather(city);
} else {
this.showError('请输入城市名称');
}
});
cityInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
const city = cityInput.value.trim();
if (city) {
this.searchWeather(city);
} else {
this.showError('请输入城市名称');
}
}
});
// 防止输入框为空时查询
cityInput.addEventListener('input', () => {
const searchBtn = document.getElementById('searchBtn');
searchBtn.disabled = !cityInput.value.trim();
});
}
async searchWeather(city) {
this.showLoading();
for (let i = 0; i < this.apiEndpoints.length; i++) {
try {
const endpoint = this.apiEndpoints[this.currentEndpointIndex];
const response = await this.fetchWeatherData(endpoint, city);
if (response && response.code === 200) {
this.displayWeatherData(response.data);
return;
}
} catch (error) {
console.warn(`API ${this.apiEndpoints[this.currentEndpointIndex]} 请求失败:`, error);
}
// 切换到下一个API端点
this.currentEndpointIndex = (this.currentEndpointIndex + 1) % this.apiEndpoints.length;
}
// 所有API都失败了
this.showError('获取天气信息失败,请检查网络连接或稍后重试');
}
async fetchWeatherData(endpoint, city) {
const url = `${endpoint}/v2/weather?query=${encodeURIComponent(city)}`;
const response = await fetch(url, {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
timeout: 10000
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return await response.json();
}
displayWeatherData(data) {
const { location, realtime } = data;
// 显示位置信息
document.getElementById('locationName').textContent = location.formatted;
document.getElementById('locationDetail').textContent =
`${location.province} ${location.city} | 邮编: ${location.zip_code}`;
// 显示当前天气
document.getElementById('temperature').textContent = realtime.temperature;
document.getElementById('weatherCondition').textContent = realtime.weather;
// 体感温度转换API返回的是华氏度需要转换为摄氏度
const feelsLikeCelsius = this.fahrenheitToCelsius(realtime.temperature_feels_like);
document.getElementById('feelsLike').textContent =
`体感温度 ${feelsLikeCelsius}°C`;
// 显示天气详情
document.getElementById('humidity').textContent = `${realtime.humidity}%`;
document.getElementById('windDirection').textContent = realtime.wind_direction;
document.getElementById('windStrength').textContent = realtime.wind_strength;
document.getElementById('pressure').textContent = `${realtime.pressure} hPa`;
document.getElementById('visibility').textContent = realtime.visibility;
// 空气质量显示
const aqiElement = document.getElementById('aqi');
aqiElement.textContent = `${realtime.aqi} (PM2.5: ${realtime.pm25})`;
aqiElement.className = this.getAQIClass(realtime.aqi);
// 显示生活指数
const lifeIndex = realtime.life_index;
this.displayLifeIndex('comfort', lifeIndex.comfort);
this.displayLifeIndex('clothing', lifeIndex.clothing);
this.displayLifeIndex('umbrella', lifeIndex.umbrella);
this.displayLifeIndex('uv', lifeIndex.uv);
this.displayLifeIndex('travel', lifeIndex.travel);
this.displayLifeIndex('sport', lifeIndex.sport);
// 显示更新时间
document.getElementById('updateTime').textContent =
`${realtime.updated} (${realtime.updated_at})`;
this.showWeatherContainer();
}
displayLifeIndex(type, indexData) {
const levelElement = document.getElementById(`${type}Level`);
const descElement = document.getElementById(`${type}Desc`);
if (levelElement && descElement && indexData) {
levelElement.textContent = indexData.level;
descElement.textContent = indexData.desc;
// 根据指数级别设置颜色
levelElement.className = this.getIndexLevelClass(indexData.level);
}
}
getAQIClass(aqi) {
if (aqi <= 50) return 'aqi-good';
if (aqi <= 100) return 'aqi-moderate';
if (aqi <= 150) return 'aqi-unhealthy-sensitive';
if (aqi <= 200) return 'aqi-unhealthy';
if (aqi <= 300) return 'aqi-very-unhealthy';
return 'aqi-hazardous';
}
getIndexLevelClass(level) {
const levelMap = {
'优': 'level-excellent',
'良': 'level-good',
'适宜': 'level-suitable',
'舒适': 'level-comfortable',
'较适宜': 'level-fairly-suitable',
'不宜': 'level-unsuitable',
'较不宜': 'level-fairly-unsuitable',
'带伞': 'level-bring-umbrella',
'最弱': 'level-weakest',
'弱': 'level-weak',
'中等': 'level-moderate',
'强': 'level-strong',
'很强': 'level-very-strong'
};
return levelMap[level] || 'level-default';
}
// 华氏度转摄氏度
fahrenheitToCelsius(fahrenheit) {
const celsius = (fahrenheit - 32) * 5 / 9;
return Math.round(celsius * 10) / 10; // 保留一位小数
}
showLoading() {
document.getElementById('loading').style.display = 'block';
document.getElementById('weatherContainer').style.display = 'none';
document.getElementById('errorMessage').style.display = 'none';
}
showWeatherContainer() {
document.getElementById('loading').style.display = 'none';
document.getElementById('weatherContainer').style.display = 'block';
document.getElementById('errorMessage').style.display = 'none';
}
showError(message) {
document.getElementById('loading').style.display = 'none';
document.getElementById('weatherContainer').style.display = 'none';
const errorElement = document.getElementById('errorMessage');
errorElement.style.display = 'block';
errorElement.querySelector('p').textContent = message;
}
}
// 添加生活指数级别样式
const style = document.createElement('style');
style.textContent = `
.aqi-good { color: #52c41a; }
.aqi-moderate { color: #faad14; }
.aqi-unhealthy-sensitive { color: #fa8c16; }
.aqi-unhealthy { color: #f5222d; }
.aqi-very-unhealthy { color: #a0206e; }
.aqi-hazardous { color: #722ed1; }
.level-excellent, .level-suitable, .level-comfortable { color: #52c41a; }
.level-good, .level-fairly-suitable { color: #1890ff; }
.level-bring-umbrella, .level-moderate { color: #faad14; }
.level-unsuitable, .level-fairly-unsuitable { color: #f5222d; }
.level-weakest, .level-weak { color: #52c41a; }
.level-strong, .level-very-strong { color: #fa8c16; }
.level-default { color: #666; }
`;
document.head.appendChild(style);
// 页面加载完成后初始化应用
document.addEventListener('DOMContentLoaded', () => {
new WeatherApp();
});
// 添加页面可见性检测,当页面重新可见时刷新数据
document.addEventListener('visibilitychange', () => {
if (!document.hidden) {
const cityInput = document.getElementById('cityInput');
const city = cityInput.value.trim() || '北京';
// 延迟1秒刷新避免频繁请求
setTimeout(() => {
if (window.weatherApp) {
window.weatherApp.searchWeather(city);
}
}, 1000);
}
});
// 将应用实例暴露到全局,方便调试和其他功能调用
window.weatherApp = null;
document.addEventListener('DOMContentLoaded', () => {
window.weatherApp = new WeatherApp();
});

View File

@@ -1,7 +0,0 @@
[
"https://60s-cf.viki.moe",
"https://60s.viki.moe",
"https://60s.b23.run",
"https://60s.114128.xyz",
"https://60s-cf.114128.xyz"
]

View File

@@ -1,68 +0,0 @@
{
"code": 200,
"message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s反馈群 595941841",
"data": {
"location": {
"province": "北京",
"city": "北京",
"town": "北京",
"formatted": "北京",
"location_id": "101010100",
"detail_url": "http://www.weather.com.cn/weather/101010100.shtml",
"is_province": true,
"is_city": false,
"is_town": false,
"area_code": "10",
"zip_code": "100000"
},
"realtime": {
"weather": "小雨转多云",
"weather_desc": "未知",
"weather_code": "d7",
"temperature": 26,
"temperature_feels_like": 81.1,
"humidity": 78,
"wind_direction": "南风转北风",
"wind_strength": "\u003C3级",
"wind_speed": "5km/h",
"pressure": 1008,
"visibility": "8km",
"aqi": 37,
"pm25": 37,
"rainfall": 0,
"rainfall_24h": 0,
"updated": "2025-08-29 08:00:00",
"updated_at": "15:10",
"life_index": {
"comfort": {
"level": "舒适",
"desc": "白天温度宜人,风力不大。"
},
"clothing": {
"level": "舒适",
"desc": "建议穿长袖衬衫单裤等服装。"
},
"umbrella": {
"level": "带伞",
"desc": "有降水,带雨伞,短期外出可收起雨伞。"
},
"uv": {
"level": "最弱",
"desc": "辐射弱涂擦SPF8-12防晒护肤品。"
},
"car_wash": {
"level": "不宜",
"desc": "有雨,雨水和泥水会弄脏爱车。"
},
"travel": {
"level": "适宜",
"desc": "较弱降水和微风将伴您共赴旅程。"
},
"sport": {
"level": "较不宜",
"desc": "有降水,推荐您在室内进行休闲运动。"
}
}
}
}
}

View File

@@ -1,132 +0,0 @@
/* 背景样式文件 - 独立分离便于迁移 */
/* 主背景渐变 */
body {
background: linear-gradient(135deg,
#e8f5e8 0%,
#f1f8e9 25%,
#e8f5e8 50%,
#c8e6c9 75%,
#e8f5e8 100%);
background-size: 400% 400%;
animation: backgroundShift 15s ease-in-out infinite;
position: relative;
}
/* 背景动画 */
@keyframes backgroundShift {
0%, 100% {
background-position: 0% 50%;
}
25% {
background-position: 100% 50%;
}
50% {
background-position: 50% 100%;
}
75% {
background-position: 50% 0%;
}
}
/* 背景装饰元素 */
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image:
radial-gradient(circle at 20% 20%, rgba(76, 175, 80, 0.1) 0%, transparent 50%),
radial-gradient(circle at 80% 80%, rgba(129, 199, 132, 0.1) 0%, transparent 50%),
radial-gradient(circle at 40% 60%, rgba(165, 214, 167, 0.08) 0%, transparent 50%);
pointer-events: none;
z-index: -1;
animation: floatingBubbles 20s ease-in-out infinite;
}
@keyframes floatingBubbles {
0%, 100% {
transform: translateY(0px) rotate(0deg);
opacity: 1;
}
33% {
transform: translateY(-20px) rotate(120deg);
opacity: 0.8;
}
66% {
transform: translateY(10px) rotate(240deg);
opacity: 0.9;
}
}
/* 背景粒子效果 */
body::after {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image:
radial-gradient(2px 2px at 20px 30px, rgba(76, 175, 80, 0.3), transparent),
radial-gradient(2px 2px at 40px 70px, rgba(129, 199, 132, 0.2), transparent),
radial-gradient(1px 1px at 90px 40px, rgba(165, 214, 167, 0.3), transparent),
radial-gradient(1px 1px at 130px 80px, rgba(76, 175, 80, 0.2), transparent),
radial-gradient(2px 2px at 160px 30px, rgba(129, 199, 132, 0.3), transparent);
background-repeat: repeat;
background-size: 200px 100px;
pointer-events: none;
z-index: -1;
animation: particleFloat 25s linear infinite;
}
@keyframes particleFloat {
0% {
transform: translateY(0px);
}
100% {
transform: translateY(-100px);
}
}
/* 响应式背景调整 */
@media (max-width: 768px) {
body::after {
background-size: 150px 75px;
animation-duration: 20s;
}
body::before {
animation-duration: 15s;
}
}
@media (max-width: 480px) {
body::after {
background-size: 100px 50px;
animation-duration: 15s;
}
body::before {
animation-duration: 12s;
}
body {
animation-duration: 12s;
}
}
/* 高性能模式 - 减少动画 */
@media (prefers-reduced-motion: reduce) {
body,
body::before,
body::after {
animation: none;
}
body {
background: linear-gradient(135deg, #e8f5e8 0%, #f1f8e9 50%, #c8e6c9 100%);
}
}

View File

@@ -1,468 +0,0 @@
/* 基础样式重置 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
line-height: 1.6;
color: #2d5a3d;
min-height: 100vh;
overflow-x: hidden;
}
/* 容器样式 */
.container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
min-height: 100vh;
display: flex;
flex-direction: column;
position: relative;
z-index: 1;
}
/* 头部样式 */
.header {
text-align: center;
margin-bottom: 40px;
padding: 40px 20px;
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(20px);
border-radius: 20px;
box-shadow: 0 8px 32px rgba(76, 175, 80, 0.1);
border: 1px solid rgba(76, 175, 80, 0.2);
position: relative;
overflow: hidden;
}
.header::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 4px;
background: linear-gradient(90deg, transparent, #4caf50, transparent);
animation: headerGlow 3s ease-in-out infinite;
}
@keyframes headerGlow {
0% { left: -100%; }
50% { left: 100%; }
100% { left: 100%; }
}
.header h1 {
font-size: 2.5rem;
font-weight: 700;
background: linear-gradient(135deg, #4caf50, #81c784, #4caf50);
background-size: 200% 200%;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
margin-bottom: 10px;
animation: titleGradient 4s ease-in-out infinite;
}
@keyframes titleGradient {
0%, 100% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
}
.header p {
font-size: 1.1rem;
color: #66bb6a;
opacity: 0.9;
}
/* 主要内容区域 */
.main {
flex: 1;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 40px;
align-items: start;
}
/* 表单容器 */
.form-container {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(20px);
padding: 35px;
border-radius: 20px;
box-shadow: 0 8px 32px rgba(76, 175, 80, 0.1);
border: 1px solid rgba(76, 175, 80, 0.2);
transition: all 0.3s ease;
}
.form-container:hover {
transform: translateY(-5px);
box-shadow: 0 12px 40px rgba(76, 175, 80, 0.15);
}
/* 表单样式 */
.qr-form {
display: flex;
flex-direction: column;
gap: 25px;
}
.input-group {
display: flex;
flex-direction: column;
gap: 8px;
}
.input-group label {
font-weight: 600;
color: #2d5a3d;
font-size: 0.95rem;
}
textarea, select {
padding: 12px 16px;
border: 2px solid rgba(76, 175, 80, 0.3);
border-radius: 12px;
font-size: 1rem;
background: rgba(255, 255, 255, 0.9);
transition: all 0.3s ease;
resize: vertical;
}
textarea {
min-height: 100px;
font-family: inherit;
}
textarea:focus, select:focus {
outline: none;
border-color: #4caf50;
box-shadow: 0 0 0 3px rgba(76, 175, 80, 0.1);
background: rgba(255, 255, 255, 1);
}
.options-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 20px;
}
/* 按钮样式 */
.generate-btn {
padding: 15px 30px;
background: linear-gradient(135deg, #4caf50, #66bb6a);
color: white;
border: none;
border-radius: 12px;
font-size: 1.1rem;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
letter-spacing: 0.5px;
}
.generate-btn::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
transition: left 0.5s ease;
}
.generate-btn:hover::before {
left: 100%;
}
.generate-btn:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(76, 175, 80, 0.3);
}
.generate-btn:active {
transform: translateY(0);
}
.generate-btn.loading .btn-text {
display: none;
}
.generate-btn.loading .btn-loading {
display: inline;
}
.btn-loading {
display: none;
}
/* 结果容器 */
.result-container {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(20px);
padding: 35px;
border-radius: 20px;
box-shadow: 0 8px 32px rgba(76, 175, 80, 0.1);
border: 1px solid rgba(76, 175, 80, 0.2);
min-height: 400px;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
}
/* 加载动画 */
.loading {
text-align: center;
color: #4caf50;
}
.loading-spinner {
width: 50px;
height: 50px;
border: 4px solid rgba(76, 175, 80, 0.2);
border-top: 4px solid #4caf50;
border-radius: 50%;
animation: spin 1s linear infinite;
margin: 0 auto 20px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* 错误样式 */
.error {
text-align: center;
color: #d32f2f;
}
.error-icon {
font-size: 3rem;
margin-bottom: 15px;
}
.error-message {
font-size: 1.1rem;
margin-bottom: 20px;
color: #666;
}
.retry-btn {
padding: 10px 20px;
background: #4caf50;
color: white;
border: none;
border-radius: 8px;
cursor: pointer;
transition: all 0.3s ease;
}
.retry-btn:hover {
background: #45a049;
transform: translateY(-1px);
}
/* 结果显示 */
.result {
width: 100%;
text-align: center;
}
.qr-display {
margin-bottom: 25px;
}
.qr-display img {
max-width: 100%;
height: auto;
border-radius: 12px;
box-shadow: 0 4px 20px rgba(76, 175, 80, 0.2);
transition: all 0.3s ease;
}
.qr-display img:hover {
transform: scale(1.05);
box-shadow: 0 8px 30px rgba(76, 175, 80, 0.3);
}
.result-info {
display: flex;
flex-direction: column;
gap: 20px;
}
.result-text {
font-size: 1rem;
color: #666;
word-break: break-all;
background: rgba(76, 175, 80, 0.1);
padding: 12px;
border-radius: 8px;
border-left: 4px solid #4caf50;
}
.result-actions {
display: flex;
gap: 10px;
justify-content: center;
flex-wrap: wrap;
}
.download-btn, .copy-btn, .new-btn {
padding: 10px 16px;
border: none;
border-radius: 8px;
cursor: pointer;
font-size: 0.9rem;
font-weight: 500;
transition: all 0.3s ease;
}
.download-btn {
background: #4caf50;
color: white;
}
.copy-btn {
background: #2196f3;
color: white;
}
.new-btn {
background: #ff9800;
color: white;
}
.download-btn:hover, .copy-btn:hover, .new-btn:hover {
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}
/* 隐藏类 */
.hidden {
display: none !important;
}
/* 页脚样式 */
.footer {
text-align: center;
margin-top: 40px;
padding: 25px;
background: rgba(255, 255, 255, 0.9);
backdrop-filter: blur(15px);
border-radius: 15px;
color: #66bb6a;
font-size: 0.9rem;
border: 1px solid rgba(76, 175, 80, 0.1);
}
/* 平板端适配 (768px - 1024px) */
@media (max-width: 1024px) and (min-width: 768px) {
.container {
max-width: 95%;
padding: 15px;
}
.main {
gap: 30px;
}
.header h1 {
font-size: 2.2rem;
}
.form-container, .result-container {
padding: 25px;
}
.options-grid {
grid-template-columns: repeat(2, 1fr);
}
}
/* 手机端适配 (最大768px) */
@media (max-width: 768px) {
.container {
padding: 10px;
}
.header {
margin-bottom: 25px;
padding: 25px 15px;
}
.header h1 {
font-size: 1.8rem;
}
.header p {
font-size: 1rem;
}
.main {
grid-template-columns: 1fr;
gap: 25px;
}
.form-container, .result-container {
padding: 20px;
}
.options-grid {
grid-template-columns: 1fr;
gap: 15px;
}
.result-actions {
flex-direction: column;
align-items: center;
}
.download-btn, .copy-btn, .new-btn {
width: 100%;
max-width: 200px;
}
}
/* 小屏手机适配 (最大480px) */
@media (max-width: 480px) {
.container {
padding: 8px;
}
.header {
padding: 20px 10px;
margin-bottom: 20px;
}
.header h1 {
font-size: 1.6rem;
}
.form-container, .result-container {
padding: 15px;
border-radius: 15px;
}
.generate-btn {
padding: 12px 20px;
font-size: 1rem;
}
textarea {
min-height: 80px;
}
.qr-display img {
max-width: 90%;
}
}

View File

@@ -1,98 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>二维码生成器</title>
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="css/background.css">
</head>
<body>
<div class="container">
<header class="header">
<h1>🔗 二维码生成器</h1>
<p>快速生成高质量二维码</p>
</header>
<main class="main">
<div class="form-container">
<form id="qrForm" class="qr-form">
<div class="input-group">
<label for="text">文本内容</label>
<textarea id="text" name="text" placeholder="请输入要生成二维码的文本或URL" required></textarea>
</div>
<div class="options-grid">
<div class="input-group">
<label for="size">尺寸大小</label>
<select id="size" name="size">
<option value="128">128x128</option>
<option value="256" selected>256x256</option>
<option value="512">512x512</option>
<option value="1024">1024x1024</option>
</select>
</div>
<div class="input-group">
<label for="level">容错级别</label>
<select id="level" name="level">
<option value="L">L - 低 (7%)</option>
<option value="M" selected>M - 中 (15%)</option>
<option value="Q">Q - 高 (25%)</option>
<option value="H">H - 最高 (30%)</option>
</select>
</div>
<div class="input-group">
<label for="encoding">返回格式</label>
<select id="encoding" name="encoding">
<option value="image" selected>图片</option>
<option value="json">JSON</option>
<option value="text">文本</option>
</select>
</div>
</div>
<button type="submit" class="generate-btn">
<span class="btn-text">生成二维码</span>
<span class="btn-loading">生成中...</span>
</button>
</form>
</div>
<div class="result-container">
<div id="loading" class="loading hidden">
<div class="loading-spinner"></div>
<p>正在生成二维码...</p>
</div>
<div id="error" class="error hidden">
<div class="error-icon">⚠️</div>
<p class="error-message"></p>
<button class="retry-btn">重试</button>
</div>
<div id="result" class="result hidden">
<div class="qr-display">
<img id="qrImage" src="" alt="生成的二维码">
</div>
<div class="result-info">
<p class="result-text"></p>
<div class="result-actions">
<button class="download-btn">下载二维码</button>
<button class="copy-btn">复制链接</button>
<button class="new-btn">生成新的</button>
</div>
</div>
</div>
</div>
</main>
<footer class="footer">
<p>© 2024 二维码生成器 - 简单快捷的二维码生成工具</p>
</footer>
</div>
<script src="js/script.js"></script>
</body>
</html>

View File

@@ -1,417 +0,0 @@
// 二维码生成器 JavaScript
class QRCodeGenerator {
constructor() {
this.apiEndpoints = [];
this.currentApiIndex = 0;
this.init();
}
// 初始化
async init() {
await this.loadApiEndpoints();
this.bindEvents();
this.setupFormValidation();
}
// 加载API接口列表
async loadApiEndpoints() {
try {
const response = await fetch('./接口集合.json');
this.apiEndpoints = await response.json();
console.log('已加载API接口:', this.apiEndpoints);
} catch (error) {
console.error('加载API接口失败:', error);
this.showError('加载配置失败,请刷新页面重试');
}
}
// 绑定事件
bindEvents() {
const form = document.getElementById('qrForm');
const retryBtn = document.querySelector('.retry-btn');
const downloadBtn = document.querySelector('.download-btn');
const copyBtn = document.querySelector('.copy-btn');
const newBtn = document.querySelector('.new-btn');
form.addEventListener('submit', (e) => this.handleSubmit(e));
retryBtn.addEventListener('click', () => this.retryGeneration());
downloadBtn.addEventListener('click', () => this.downloadQRCode());
copyBtn.addEventListener('click', () => this.copyImageLink());
newBtn.addEventListener('click', () => this.resetForm());
// 实时字符计数
const textArea = document.getElementById('text');
textArea.addEventListener('input', () => this.updateCharCount());
}
// 设置表单验证
setupFormValidation() {
const textArea = document.getElementById('text');
const form = document.getElementById('qrForm');
textArea.addEventListener('blur', () => {
if (textArea.value.trim() === '') {
this.showFieldError(textArea, '请输入要生成二维码的内容');
} else {
this.clearFieldError(textArea);
}
});
}
// 显示字段错误
showFieldError(field, message) {
this.clearFieldError(field);
field.style.borderColor = '#d32f2f';
const errorDiv = document.createElement('div');
errorDiv.className = 'field-error';
errorDiv.style.color = '#d32f2f';
errorDiv.style.fontSize = '0.8rem';
errorDiv.style.marginTop = '5px';
errorDiv.textContent = message;
field.parentNode.appendChild(errorDiv);
}
// 清除字段错误
clearFieldError(field) {
field.style.borderColor = '';
const errorDiv = field.parentNode.querySelector('.field-error');
if (errorDiv) {
errorDiv.remove();
}
}
// 更新字符计数
updateCharCount() {
const textArea = document.getElementById('text');
const text = textArea.value;
const length = text.length;
// 移除旧的计数显示
const oldCounter = textArea.parentNode.querySelector('.char-counter');
if (oldCounter) oldCounter.remove();
// 添加新的计数显示
if (length > 0) {
const counter = document.createElement('div');
counter.className = 'char-counter';
counter.style.fontSize = '0.8rem';
counter.style.color = '#666';
counter.style.textAlign = 'right';
counter.style.marginTop = '5px';
counter.textContent = `${length} 个字符`;
textArea.parentNode.appendChild(counter);
}
}
// 处理表单提交
async handleSubmit(e) {
e.preventDefault();
const formData = new FormData(e.target);
const params = {
text: formData.get('text').trim(),
size: formData.get('size'),
level: formData.get('level'),
encoding: formData.get('encoding')
};
// 验证输入
if (!params.text) {
this.showFieldError(document.getElementById('text'), '请输入要生成二维码的内容');
return;
}
this.showLoading();
await this.generateQRCode(params);
}
// 生成二维码
async generateQRCode(params) {
let success = false;
let lastError = null;
// 尝试所有API接口
for (let i = 0; i < this.apiEndpoints.length; i++) {
const apiIndex = (this.currentApiIndex + i) % this.apiEndpoints.length;
const apiUrl = this.apiEndpoints[apiIndex];
try {
console.log(`尝试API ${apiIndex + 1}:`, apiUrl);
const result = await this.callAPI(apiUrl, params);
if (result.success) {
this.currentApiIndex = apiIndex; // 记录成功的API
this.showResult(result.data, params);
success = true;
break;
}
} catch (error) {
console.warn(`API ${apiIndex + 1} 失败:`, error);
lastError = error;
}
}
if (!success) {
this.showError(lastError?.message || '所有API接口都无法访问请稍后重试');
}
}
// 调用API
async callAPI(baseUrl, params) {
const url = new URL('/v2/qrcode', baseUrl);
// 添加查询参数
Object.entries(params).forEach(([key, value]) => {
if (value) {
url.searchParams.append(key, value);
}
});
console.log('请求URL:', url.toString());
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 10000); // 10秒超时
try {
const response = await fetch(url.toString(), {
method: 'GET',
signal: controller.signal,
headers: {
'Accept': 'application/json, image/*'
}
});
clearTimeout(timeoutId);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
// 根据返回格式处理
if (params.encoding === 'image') {
const blob = await response.blob();
const imageUrl = URL.createObjectURL(blob);
return {
success: true,
data: {
imageUrl: imageUrl,
text: params.text,
size: params.size,
level: params.level,
format: 'image'
}
};
} else {
const jsonData = await response.json();
if (jsonData.code === 0 && jsonData.data) {
return {
success: true,
data: {
imageUrl: jsonData.data.data_uri,
text: params.text,
size: params.size,
level: params.level,
format: 'json',
base64: jsonData.data.base64,
mimeType: jsonData.data.mime_type
}
};
} else {
throw new Error(jsonData.message || '生成失败');
}
}
} catch (error) {
clearTimeout(timeoutId);
if (error.name === 'AbortError') {
throw new Error('请求超时,请重试');
}
throw error;
}
}
// 显示加载状态
showLoading() {
this.hideAllStates();
document.getElementById('loading').classList.remove('hidden');
const btn = document.querySelector('.generate-btn');
btn.classList.add('loading');
btn.disabled = true;
}
// 显示错误
showError(message) {
this.hideAllStates();
const errorDiv = document.getElementById('error');
const errorMessage = errorDiv.querySelector('.error-message');
errorMessage.textContent = message;
errorDiv.classList.remove('hidden');
this.resetButton();
}
// 显示结果
showResult(data, params) {
this.hideAllStates();
const resultDiv = document.getElementById('result');
const qrImage = document.getElementById('qrImage');
const resultText = document.querySelector('.result-text');
qrImage.src = data.imageUrl;
qrImage.alt = `二维码: ${data.text}`;
resultText.innerHTML = `
<strong>内容:</strong> ${this.escapeHtml(data.text)}<br>
<strong>尺寸:</strong> ${data.size}x${data.size}<br>
<strong>容错级别:</strong> ${data.level}<br>
<strong>格式:</strong> ${data.format.toUpperCase()}
`;
resultDiv.classList.remove('hidden');
this.resetButton();
// 保存数据供下载使用
this.currentQRData = data;
}
// 隐藏所有状态
hideAllStates() {
document.getElementById('loading').classList.add('hidden');
document.getElementById('error').classList.add('hidden');
document.getElementById('result').classList.add('hidden');
}
// 重置按钮状态
resetButton() {
const btn = document.querySelector('.generate-btn');
btn.classList.remove('loading');
btn.disabled = false;
}
// 重试生成
async retryGeneration() {
const form = document.getElementById('qrForm');
const formData = new FormData(form);
const params = {
text: formData.get('text').trim(),
size: formData.get('size'),
level: formData.get('level'),
encoding: formData.get('encoding')
};
this.showLoading();
await this.generateQRCode(params);
}
// 下载二维码
downloadQRCode() {
if (!this.currentQRData) return;
const link = document.createElement('a');
link.href = this.currentQRData.imageUrl;
link.download = `qrcode_${Date.now()}.png`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
this.showToast('二维码已下载');
}
// 复制图片链接
async copyImageLink() {
if (!this.currentQRData) return;
try {
await navigator.clipboard.writeText(this.currentQRData.imageUrl);
this.showToast('链接已复制到剪贴板');
} catch (error) {
console.error('复制失败:', error);
this.showToast('复制失败,请手动复制');
}
}
// 重置表单
resetForm() {
document.getElementById('qrForm').reset();
this.hideAllStates();
this.currentQRData = null;
// 清除字符计数
const counter = document.querySelector('.char-counter');
if (counter) counter.remove();
// 清除字段错误
document.querySelectorAll('input, textarea, select').forEach(field => {
this.clearFieldError(field);
});
// 聚焦到文本框
document.getElementById('text').focus();
}
// 显示提示消息
showToast(message) {
// 移除旧的toast
const oldToast = document.querySelector('.toast');
if (oldToast) oldToast.remove();
const toast = document.createElement('div');
toast.className = 'toast';
toast.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
background: #4caf50;
color: white;
padding: 12px 20px;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0,0,0,0.2);
z-index: 1000;
animation: slideIn 0.3s ease;
`;
toast.textContent = message;
document.body.appendChild(toast);
setTimeout(() => {
toast.style.animation = 'slideOut 0.3s ease';
setTimeout(() => toast.remove(), 300);
}, 3000);
}
// HTML转义
escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
}
// 添加CSS动画
const style = document.createElement('style');
style.textContent = `
@keyframes slideIn {
from { transform: translateX(100%); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
@keyframes slideOut {
from { transform: translateX(0); opacity: 1; }
to { transform: translateX(100%); opacity: 0; }
}
`;
document.head.appendChild(style);
// 页面加载完成后初始化
document.addEventListener('DOMContentLoaded', () => {
new QRCodeGenerator();
});
// 错误处理
window.addEventListener('error', (e) => {
console.error('全局错误:', e.error);
});
window.addEventListener('unhandledrejection', (e) => {
console.error('未处理的Promise拒绝:', e.reason);
});

View File

@@ -1,7 +0,0 @@
[
"https://60s-cf.viki.moe",
"https://60s.viki.moe",
"https://60s.b23.run",
"https://60s.114128.xyz",
"https://60s-cf.114128.xyz"
]

View File

@@ -1,10 +0,0 @@
{
"code": 0,
"message": "success",
"data": {
"base64": "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAACAASURBVHic7Z15fBTV...",
"data_uri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAACAASURBVHic7Z15fBTV...",
"mime_type": "image/png",
"text": "https://example.com"
}
}

View File

@@ -1,192 +0,0 @@
/* 彩虹渐变背景样式 */
/* 主背景渐变 */
body {
background: linear-gradient(
135deg,
rgba(255, 107, 107, 0.3) 0%,
rgba(255, 165, 0, 0.3) 14.28%,
rgba(255, 255, 0, 0.25) 28.56%,
rgba(50, 205, 50, 0.3) 42.84%,
rgba(0, 191, 255, 0.3) 57.12%,
rgba(65, 105, 225, 0.3) 71.4%,
rgba(147, 112, 219, 0.3) 85.68%,
rgba(255, 105, 180, 0.3) 100%
);
background-size: 400% 400%;
animation: rainbowShift 20s ease infinite;
min-height: 100vh;
}
/* 彩虹渐变动画 */
@keyframes rainbowShift {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
/* 半透明覆盖层,增强可读性 */
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(255, 255, 255, 0.4);
backdrop-filter: blur(2px);
z-index: -1;
pointer-events: none;
}
/* 搜索按钮彩虹渐变 */
.search-btn {
background: linear-gradient(
45deg,
rgba(255, 107, 107, 0.8),
rgba(255, 165, 0, 0.8),
rgba(255, 255, 0, 0.7),
rgba(50, 205, 50, 0.8),
rgba(0, 191, 255, 0.8),
rgba(65, 105, 225, 0.8),
rgba(147, 112, 219, 0.8)
);
background-size: 300% 300%;
animation: buttonRainbow 12s ease infinite;
}
@keyframes buttonRainbow {
0%, 100% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
}
/* 结果卡片边框彩虹渐变 */
.result-card {
position: relative;
overflow: hidden;
}
.result-card::before {
content: '';
position: absolute;
top: -2px;
left: -2px;
right: -2px;
bottom: -2px;
background: linear-gradient(
45deg,
rgba(255, 107, 107, 0.4),
rgba(255, 165, 0, 0.4),
rgba(255, 255, 0, 0.3),
rgba(50, 205, 50, 0.4),
rgba(0, 191, 255, 0.4),
rgba(65, 105, 225, 0.4),
rgba(147, 112, 219, 0.4),
rgba(255, 107, 107, 0.4)
);
background-size: 400% 400%;
animation: borderRainbow 15s linear infinite;
border-radius: inherit;
z-index: -1;
}
@keyframes borderRainbow {
0% {
background-position: 0% 50%;
}
100% {
background-position: 400% 50%;
}
}
/* 加载动画彩虹效果 */
.loading-spinner {
border: 4px solid rgba(255, 255, 255, 0.3);
border-top: 4px solid transparent;
border-image: linear-gradient(
45deg,
#ff6b6b,
#ffa500,
#ffff00,
#32cd32,
#00bfff,
#4169e1,
#9370db
) 1;
animation: spin 1s linear infinite, colorShift 3s ease infinite;
}
@keyframes colorShift {
0%, 100% {
filter: hue-rotate(0deg);
}
50% {
filter: hue-rotate(180deg);
}
}
/* 链接悬停彩虹效果 */
.result-link:hover {
background: linear-gradient(
90deg,
rgba(255, 107, 107, 0.7),
rgba(255, 165, 0, 0.7),
rgba(255, 255, 0, 0.6),
rgba(50, 205, 50, 0.7),
rgba(0, 191, 255, 0.7),
rgba(65, 105, 225, 0.7),
rgba(147, 112, 219, 0.7)
);
background-size: 200% 200%;
animation: linkRainbow 3s ease infinite;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
@keyframes linkRainbow {
0%, 100% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
}
/* 标题彩虹文字效果 */
.title {
background: linear-gradient(
90deg,
rgba(255, 107, 107, 0.8),
rgba(255, 165, 0, 0.8),
rgba(255, 255, 0, 0.7),
rgba(50, 205, 50, 0.8),
rgba(0, 191, 255, 0.8),
rgba(65, 105, 225, 0.8),
rgba(147, 112, 219, 0.8)
);
background-size: 200% 200%;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
animation: titleRainbow 8s ease infinite;
}
@keyframes titleRainbow {
0%, 100% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
}

View File

@@ -1,530 +0,0 @@
/* 基础样式重置 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Microsoft YaHei', 'PingFang SC', 'Helvetica Neue', Arial, sans-serif;
line-height: 1.6;
color: #333;
overflow-x: hidden;
}
/* 容器布局 */
.container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
min-height: 100vh;
display: flex;
flex-direction: column;
}
/* 头部样式 */
.header {
text-align: center;
margin-bottom: 40px;
padding: 20px 0;
}
.title {
font-size: 2.5rem;
font-weight: 700;
margin-bottom: 10px;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1);
}
.subtitle {
font-size: 1.1rem;
color: rgba(255, 255, 255, 0.9);
font-weight: 300;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
}
/* 主内容区域 */
.main {
flex: 1;
display: flex;
flex-direction: column;
gap: 30px;
}
/* 搜索区域 */
.search-section {
display: flex;
justify-content: center;
align-items: center;
}
.search-container {
display: flex;
width: 100%;
max-width: 600px;
background: rgba(255, 255, 255, 0.95);
border-radius: 50px;
padding: 8px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
backdrop-filter: blur(10px);
transition: all 0.3s ease;
}
.search-container:focus-within {
transform: translateY(-2px);
box-shadow: 0 15px 40px rgba(0, 0, 0, 0.3);
}
.search-input {
flex: 1;
border: none;
outline: none;
padding: 15px 25px;
font-size: 1.1rem;
background: transparent;
color: #333;
border-radius: 50px;
}
.search-input::placeholder {
color: #999;
font-weight: 300;
}
.search-btn {
border: none;
outline: none;
padding: 15px 25px;
border-radius: 50px;
color: white;
font-size: 1rem;
font-weight: 600;
cursor: pointer;
display: flex;
align-items: center;
gap: 8px;
transition: all 0.3s ease;
min-width: 120px;
justify-content: center;
}
.search-btn:hover {
transform: scale(1.05);
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
}
.search-btn:active {
transform: scale(0.98);
}
.search-icon {
font-size: 1.2rem;
}
/* 结果区域 */
.result-section {
flex: 1;
display: flex;
justify-content: center;
align-items: flex-start;
min-height: 400px;
}
/* 加载动画 */
.loading {
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
padding: 40px;
color: rgba(255, 255, 255, 0.9);
}
.loading-spinner {
width: 50px;
height: 50px;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* 结果卡片 */
.result-card {
width: 100%;
max-width: 800px;
background: rgba(255, 255, 255, 0.95);
border-radius: 20px;
padding: 30px;
box-shadow: 0 15px 40px rgba(0, 0, 0, 0.2);
backdrop-filter: blur(10px);
animation: slideUp 0.5s ease;
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.result-header {
margin-bottom: 25px;
text-align: center;
}
.result-title {
font-size: 2rem;
font-weight: 700;
color: #333;
margin-bottom: 10px;
}
.result-description {
font-size: 1.1rem;
color: #666;
font-weight: 400;
}
.result-content {
display: grid;
grid-template-columns: 1fr 2fr;
gap: 30px;
align-items: start;
}
.result-image-container {
display: flex;
justify-content: center;
}
.result-image {
width: 100%;
max-width: 250px;
height: auto;
border-radius: 15px;
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
transition: transform 0.3s ease;
}
.result-image:hover {
transform: scale(1.05);
}
.result-text {
display: flex;
flex-direction: column;
gap: 20px;
}
.result-abstract h3 {
font-size: 1.3rem;
color: #333;
margin-bottom: 10px;
font-weight: 600;
}
.result-abstract p {
font-size: 1rem;
line-height: 1.8;
color: #555;
text-align: justify;
}
.result-actions {
display: flex;
justify-content: flex-end;
}
.result-link {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 12px 24px;
background: rgba(0, 123, 255, 0.1);
color: #007bff;
text-decoration: none;
border-radius: 25px;
font-weight: 600;
transition: all 0.3s ease;
border: 2px solid transparent;
}
.result-link:hover {
background: rgba(0, 123, 255, 0.2);
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(0, 123, 255, 0.3);
}
.link-icon {
font-size: 1.2rem;
transition: transform 0.3s ease;
}
.result-link:hover .link-icon {
transform: translateX(5px);
}
/* 错误消息 */
.error-message {
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
padding: 40px;
background: rgba(255, 255, 255, 0.95);
border-radius: 20px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
backdrop-filter: blur(10px);
text-align: center;
max-width: 500px;
width: 100%;
}
.error-icon {
font-size: 3rem;
}
.error-message h3 {
color: #e74c3c;
font-size: 1.5rem;
margin-bottom: 10px;
}
.error-message p {
color: #666;
font-size: 1rem;
line-height: 1.6;
}
.retry-btn {
padding: 12px 24px;
background: #e74c3c;
color: white;
border: none;
border-radius: 25px;
font-size: 1rem;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
}
.retry-btn:hover {
background: #c0392b;
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(231, 76, 60, 0.3);
}
/* 欢迎消息 */
.welcome-message {
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
padding: 60px 40px;
background: rgba(255, 255, 255, 0.9);
border-radius: 20px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
backdrop-filter: blur(10px);
text-align: center;
max-width: 600px;
width: 100%;
}
.welcome-icon {
font-size: 4rem;
opacity: 0.8;
}
.welcome-message h3 {
color: #333;
font-size: 1.8rem;
font-weight: 600;
margin-bottom: 10px;
}
.welcome-message p {
color: #666;
font-size: 1.1rem;
line-height: 1.6;
max-width: 400px;
}
/* 页脚 */
.footer {
text-align: center;
padding: 20px 0;
margin-top: 40px;
color: rgba(255, 255, 255, 0.8);
font-size: 0.9rem;
}
/* 平板端适配 (768px - 1024px) */
@media (max-width: 1024px) and (min-width: 768px) {
.container {
padding: 15px;
}
.title {
font-size: 2.2rem;
}
.result-content {
grid-template-columns: 1fr 1.5fr;
gap: 25px;
}
.result-card {
padding: 25px;
}
}
/* 手机端适配 (最大768px) */
@media (max-width: 768px) {
.container {
padding: 10px;
}
.header {
margin-bottom: 30px;
padding: 15px 0;
}
.title {
font-size: 1.8rem;
}
.subtitle {
font-size: 1rem;
}
.search-container {
max-width: 100%;
padding: 6px;
}
.search-input {
padding: 12px 20px;
font-size: 1rem;
}
.search-btn {
padding: 12px 20px;
min-width: 100px;
font-size: 0.9rem;
}
.search-text {
display: none;
}
.result-card {
padding: 20px;
border-radius: 15px;
}
.result-title {
font-size: 1.5rem;
}
.result-description {
font-size: 1rem;
}
.result-content {
grid-template-columns: 1fr;
gap: 20px;
}
.result-image {
max-width: 200px;
}
.result-abstract h3 {
font-size: 1.2rem;
}
.result-abstract p {
font-size: 0.95rem;
line-height: 1.7;
}
.result-actions {
justify-content: center;
}
.welcome-message {
padding: 40px 20px;
}
.welcome-icon {
font-size: 3rem;
}
.welcome-message h3 {
font-size: 1.5rem;
}
.welcome-message p {
font-size: 1rem;
}
.error-message {
padding: 30px 20px;
}
.error-icon {
font-size: 2.5rem;
}
.error-message h3 {
font-size: 1.3rem;
}
}
/* 小屏手机适配 (最大480px) */
@media (max-width: 480px) {
.title {
font-size: 1.6rem;
}
.search-container {
flex-direction: column;
gap: 10px;
padding: 15px;
border-radius: 20px;
}
.search-input {
border-radius: 15px;
text-align: center;
}
.search-btn {
border-radius: 15px;
justify-content: center;
}
.search-text {
display: inline;
}
.result-card {
padding: 15px;
}
.result-title {
font-size: 1.3rem;
}
.result-image {
max-width: 150px;
}
}

View File

@@ -1,83 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>百度百科词条查询</title>
<link rel="stylesheet" href="css/background.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="container">
<header class="header">
<h1 class="title">百度百科词条查询</h1>
<p class="subtitle">探索知识的彩虹世界</p>
</header>
<main class="main">
<div class="search-section">
<div class="search-container">
<input type="text" id="searchInput" class="search-input" placeholder="请输入要查询的词条..." autocomplete="off">
<button id="searchBtn" class="search-btn">
<span class="search-icon">🔍</span>
<span class="search-text">搜索</span>
</button>
</div>
</div>
<div class="result-section" id="resultSection">
<div class="loading" id="loading" style="display: none;">
<div class="loading-spinner"></div>
<p>正在搜索中...</p>
</div>
<div class="result-card" id="resultCard" style="display: none;">
<div class="result-header">
<h2 class="result-title" id="resultTitle"></h2>
<p class="result-description" id="resultDescription"></p>
</div>
<div class="result-content">
<div class="result-image-container">
<img id="resultImage" class="result-image" alt="词条图片">
</div>
<div class="result-text">
<div class="result-abstract">
<h3>摘要</h3>
<p id="resultAbstract"></p>
</div>
<div class="result-actions">
<a id="resultLink" class="result-link" target="_blank">
<span>查看完整词条</span>
<span class="link-icon"></span>
</a>
</div>
</div>
</div>
</div>
<div class="error-message" id="errorMessage" style="display: none;">
<div class="error-icon">⚠️</div>
<h3>查询失败</h3>
<p id="errorText"></p>
<button id="retryBtn" class="retry-btn">重试</button>
</div>
<div class="welcome-message" id="welcomeMessage">
<div class="welcome-icon">📚</div>
<h3>欢迎使用百度百科词条查询</h3>
<p>在上方搜索框中输入您想了解的词条,开始探索知识的海洋</p>
</div>
</div>
</main>
<footer class="footer">
<p>数据来源:百度百科</p>
</footer>
</div>
<script src="js/script.js"></script>
</body>
</html>

View File

@@ -1,324 +0,0 @@
// 百度百科词条查询应用
class BaikeApp {
constructor() {
// API接口列表
this.apiEndpoints = [
'https://60s-cf.viki.moe',
'https://60s.viki.moe',
'https://60s.b23.run',
'https://60s.114128.xyz',
'https://60s-cf.114128.xyz'
];
this.currentApiIndex = 0;
this.isLoading = false;
this.initElements();
this.bindEvents();
}
// 初始化DOM元素
initElements() {
this.searchInput = document.getElementById('searchInput');
this.searchBtn = document.getElementById('searchBtn');
this.resultSection = document.getElementById('resultSection');
this.loading = document.getElementById('loading');
this.resultCard = document.getElementById('resultCard');
this.errorMessage = document.getElementById('errorMessage');
this.welcomeMessage = document.getElementById('welcomeMessage');
this.retryBtn = document.getElementById('retryBtn');
// 结果显示元素
this.resultTitle = document.getElementById('resultTitle');
this.resultDescription = document.getElementById('resultDescription');
this.resultImage = document.getElementById('resultImage');
this.resultAbstract = document.getElementById('resultAbstract');
this.resultLink = document.getElementById('resultLink');
this.errorText = document.getElementById('errorText');
}
// 绑定事件
bindEvents() {
// 搜索按钮点击事件
this.searchBtn.addEventListener('click', () => {
this.handleSearch();
});
// 输入框回车事件
this.searchInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
this.handleSearch();
}
});
// 重试按钮事件
this.retryBtn.addEventListener('click', () => {
this.handleSearch();
});
// 输入框焦点事件
this.searchInput.addEventListener('focus', () => {
this.searchInput.select();
});
}
// 处理搜索
async handleSearch() {
const query = this.searchInput.value.trim();
if (!query) {
this.showError('请输入要查询的词条');
this.searchInput.focus();
return;
}
if (this.isLoading) {
return;
}
await this.searchBaike(query);
}
// 搜索百科词条
async searchBaike(query) {
this.showLoading();
this.isLoading = true;
// 重置API索引
this.currentApiIndex = 0;
const success = await this.tryApiCall(query);
if (!success) {
this.showError('所有API接口都无法访问请稍后重试');
}
this.isLoading = false;
}
// 尝试API调用
async tryApiCall(query) {
for (let i = 0; i < this.apiEndpoints.length; i++) {
const endpoint = this.apiEndpoints[this.currentApiIndex];
try {
const result = await this.callApi(endpoint, query);
if (result) {
this.showResult(result);
return true;
}
} catch (error) {
console.warn(`API ${endpoint} 调用失败:`, error.message);
}
// 切换到下一个API
this.currentApiIndex = (this.currentApiIndex + 1) % this.apiEndpoints.length;
}
return false;
}
// 调用API
async callApi(endpoint, query) {
const url = `${endpoint}/v2/baike?word=${encodeURIComponent(query)}`;
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 10000); // 10秒超时
try {
const response = await fetch(url, {
method: 'GET',
signal: controller.signal,
headers: {
'Accept': 'application/json',
}
});
clearTimeout(timeoutId);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const data = await response.json();
if (data.code === 200 && data.data) {
return data.data;
} else {
throw new Error(data.message || '未找到相关词条');
}
} catch (error) {
clearTimeout(timeoutId);
if (error.name === 'AbortError') {
throw new Error('请求超时');
}
throw error;
}
}
// 显示加载状态
showLoading() {
this.hideAllSections();
this.loading.style.display = 'flex';
}
// 显示搜索结果
showResult(data) {
this.hideAllSections();
// 填充数据
this.resultTitle.textContent = data.title || '未知标题';
this.resultDescription.textContent = data.description || '暂无描述';
this.resultAbstract.textContent = data.abstract || '暂无摘要信息';
// 处理图片
if (data.cover) {
this.resultImage.src = data.cover;
this.resultImage.style.display = 'block';
this.resultImage.onerror = () => {
this.resultImage.style.display = 'none';
};
} else {
this.resultImage.style.display = 'none';
}
// 处理链接
if (data.link) {
this.resultLink.href = data.link;
this.resultLink.style.display = 'inline-flex';
} else {
this.resultLink.style.display = 'none';
}
this.resultCard.style.display = 'block';
// 滚动到结果区域
this.resultCard.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
}
// 显示错误信息
showError(message) {
this.hideAllSections();
this.errorText.textContent = message;
this.errorMessage.style.display = 'flex';
}
// 隐藏所有区域
hideAllSections() {
this.loading.style.display = 'none';
this.resultCard.style.display = 'none';
this.errorMessage.style.display = 'none';
this.welcomeMessage.style.display = 'none';
}
// 显示欢迎信息
showWelcome() {
this.hideAllSections();
this.welcomeMessage.style.display = 'flex';
}
}
// 工具函数
class Utils {
// 防抖函数
static debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
// 节流函数
static throttle(func, limit) {
let inThrottle;
return function() {
const args = arguments;
const context = this;
if (!inThrottle) {
func.apply(context, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}
// 格式化文本长度
static truncateText(text, maxLength) {
if (text.length <= maxLength) {
return text;
}
return text.substring(0, maxLength) + '...';
}
// 检查是否为移动设备
static isMobile() {
return window.innerWidth <= 768;
}
}
// 页面加载完成后初始化应用
document.addEventListener('DOMContentLoaded', () => {
// 初始化应用
const app = new BaikeApp();
// 添加页面可见性变化监听
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'visible') {
// 页面重新可见时,聚焦搜索框
if (!app.isLoading) {
app.searchInput.focus();
}
}
});
// 添加窗口大小变化监听
window.addEventListener('resize', Utils.throttle(() => {
// 响应式调整
if (Utils.isMobile()) {
// 移动端特殊处理
document.body.classList.add('mobile');
} else {
document.body.classList.remove('mobile');
}
}, 250));
// 初始检查设备类型
if (Utils.isMobile()) {
document.body.classList.add('mobile');
}
// 页面加载完成后聚焦搜索框
setTimeout(() => {
app.searchInput.focus();
}, 500);
// 添加键盘快捷键支持
document.addEventListener('keydown', (e) => {
// Ctrl/Cmd + K 聚焦搜索框
if ((e.ctrlKey || e.metaKey) && e.key === 'k') {
e.preventDefault();
app.searchInput.focus();
app.searchInput.select();
}
// ESC 清空搜索框
if (e.key === 'Escape') {
app.searchInput.value = '';
app.showWelcome();
app.searchInput.focus();
}
});
console.log('百度百科词条查询应用已初始化');
});

View File

@@ -1,7 +0,0 @@
[
"https://60s-cf.viki.moe",
"https://60s.viki.moe",
"https://60s.b23.run",
"https://60s.114128.xyz",
"https://60s-cf.114128.xyz"
]

View File

@@ -1,12 +0,0 @@
{
"code": 200,
"message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s反馈群 595941841",
"data": {
"title": "西游记",
"description": "明代吴承恩创作的章回体长篇神魔小说",
"abstract": "《西游记》又名《西游释厄传》,是中国古代第一部浪漫主义章回体长篇神魔小说。最早的《西游记》版本是明代万历二十年金陵世德堂《新刻出像官板大字西游记》,未署作者姓名。鲁迅、董作宾等人根据《淮安府志》“吴承恩《西游记》”的记载予以最终论定“吴承恩原著”。该小说主要讲述了孙悟空出世,并寻菩提祖师学艺及大闹天宫后,与猪八戒、沙僧和白龙马一同护送唐僧西天取经,于路上历经险阻,降妖除魔,渡过了九九八十一难,成功...",
"cover": "https://bkimg.cdn.bcebos.com/pic/b7fd5266d01609248d763e43db0735fae6cd3412?x-bce-process=image/format,f_auto",
"has_other": true,
"link": "http://baike.baidu.com/subview/2583/5315045.htm"
}
}

View File

@@ -1,388 +0,0 @@
/* 历史上的今天 - 手机端优先的响应式设计 */
/* 重置样式 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
color: #2c3e50;
line-height: 1.6;
overflow-x: hidden;
}
.container {
max-width: 100%;
margin: 0 auto;
padding: 10px;
}
/* 头部样式 - 手机端优先 */
.header {
text-align: center;
margin-bottom: 20px;
background: rgba(255, 255, 255, 0.95);
border-radius: 15px;
padding: 20px 15px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
backdrop-filter: blur(10px);
}
.header h1 {
font-size: 1.8rem;
color: #2c3e50;
margin-bottom: 8px;
font-weight: 700;
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
flex-wrap: wrap;
}
.header p {
color: #7f8c8d;
font-size: 0.9rem;
line-height: 1.4;
}
/* 日期显示 */
.date-info {
background: rgba(255, 255, 255, 0.95);
border-radius: 12px;
padding: 15px;
margin-bottom: 15px;
text-align: center;
box-shadow: 0 3px 15px rgba(0, 0, 0, 0.08);
}
.date-info h2 {
font-size: 1.3rem;
color: #2c3e50;
margin-bottom: 5px;
}
.date-info .date-text {
color: #7f8c8d;
font-size: 0.9rem;
}
/* 加载状态 */
.loading {
text-align: center;
padding: 30px 15px;
background: rgba(255, 255, 255, 0.95);
border-radius: 12px;
box-shadow: 0 3px 15px rgba(0, 0, 0, 0.08);
}
.spinner {
width: 35px;
height: 35px;
border: 3px solid #ecf0f1;
border-top: 3px solid #667eea;
border-radius: 50%;
animation: spin 1s linear infinite;
margin: 0 auto 15px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* 历史事件容器 */
.events-container {
background: rgba(255, 255, 255, 0.95);
border-radius: 15px;
padding: 15px;
margin-bottom: 15px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
backdrop-filter: blur(10px);
}
/* 统计信息 */
.stats {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 8px;
margin-bottom: 20px;
}
.stat-item {
background: rgba(102, 126, 234, 0.1);
border-radius: 10px;
padding: 12px;
text-align: center;
}
.stat-number {
font-size: 1.4rem;
font-weight: 700;
color: #667eea;
display: block;
}
.stat-label {
color: #7f8c8d;
font-size: 0.8rem;
margin-top: 3px;
}
/* 事件列表 */
.events-list {
display: flex;
flex-direction: column;
gap: 12px;
}
.event-card {
background: rgba(255, 255, 255, 0.9);
border-radius: 12px;
padding: 15px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
transition: all 0.3s ease;
border-left: 4px solid #667eea;
position: relative;
}
.event-card:hover {
transform: translateY(-2px);
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
}
/* 事件类型标签 */
.event-type {
position: absolute;
top: 10px;
right: 10px;
padding: 4px 8px;
border-radius: 12px;
font-size: 0.7rem;
font-weight: 600;
text-transform: uppercase;
}
.event-type.birth {
background: #e8f5e8;
color: #27ae60;
}
.event-type.death {
background: #fdf2e9;
color: #e67e22;
}
.event-type.event {
background: #ebf3fd;
color: #3498db;
}
/* 事件年份 */
.event-year {
font-size: 1.1rem;
font-weight: 700;
color: #667eea;
margin-bottom: 8px;
display: flex;
align-items: center;
gap: 8px;
}
.event-year::before {
content: "📅";
font-size: 1rem;
}
/* 事件标题 */
.event-title {
font-size: 1rem;
font-weight: 600;
color: #2c3e50;
margin-bottom: 8px;
line-height: 1.4;
}
/* 事件描述 */
.event-description {
color: #7f8c8d;
font-size: 0.85rem;
line-height: 1.5;
margin-bottom: 10px;
}
/* 链接按钮 */
.event-link {
display: inline-flex;
align-items: center;
gap: 5px;
color: #667eea;
text-decoration: none;
font-size: 0.8rem;
font-weight: 500;
padding: 6px 12px;
background: rgba(102, 126, 234, 0.1);
border-radius: 15px;
transition: all 0.3s ease;
}
.event-link:hover {
background: rgba(102, 126, 234, 0.2);
transform: translateX(2px);
}
.event-link::after {
content: "🔗";
font-size: 0.7rem;
}
/* 错误提示 */
.error {
background: #fed7d7;
color: #c53030;
padding: 15px;
border-radius: 12px;
text-align: center;
border: 1px solid #feb2b2;
margin: 15px 0;
font-size: 0.9rem;
}
/* 隐藏类 */
.hidden {
display: none;
}
/* 淡入动画 */
.fade-in {
animation: fadeIn 0.6s ease-in;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* 平板端适配 (768px+) */
@media (min-width: 768px) {
.container {
max-width: 750px;
padding: 20px;
}
.header {
padding: 30px 25px;
}
.header h1 {
font-size: 2.2rem;
}
.header p {
font-size: 1rem;
}
.date-info {
padding: 20px;
}
.date-info h2 {
font-size: 1.5rem;
}
.events-container {
padding: 25px;
}
.stats {
gap: 15px;
}
.event-card {
padding: 20px;
}
.event-title {
font-size: 1.1rem;
}
.event-description {
font-size: 0.9rem;
}
}
/* 电脑端适配 (1024px+) */
@media (min-width: 1024px) {
.container {
max-width: 1000px;
padding: 30px;
}
.header {
padding: 40px 35px;
}
.header h1 {
font-size: 2.5rem;
}
.events-list {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20px;
}
.event-card {
padding: 25px;
}
.event-title {
font-size: 1.2rem;
}
.event-description {
font-size: 0.95rem;
}
}
/* 大屏幕优化 (1200px+) */
@media (min-width: 1200px) {
.container {
max-width: 1200px;
padding: 40px;
}
.events-list {
grid-template-columns: repeat(3, 1fr);
gap: 25px;
}
}
/* 滚动条样式 */
::-webkit-scrollbar {
width: 6px;
}
::-webkit-scrollbar-track {
background: rgba(255, 255, 255, 0.1);
}
::-webkit-scrollbar-thumb {
background: rgba(102, 126, 234, 0.5);
border-radius: 3px;
}
::-webkit-scrollbar-thumb:hover {
background: rgba(102, 126, 234, 0.7);
}

View File

@@ -1,83 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="历史上的今天 - 了解今天在历史上发生的重要事件">
<meta name="keywords" content="历史上的今天,历史事件,百度百科,今日历史">
<title>历史上的今天 - 60s API集合</title>
<!-- 预加载关键资源 -->
<link rel="preconnect" href="https://60s.viki.moe">
<link rel="dns-prefetch" href="https://60s.viki.moe">
<!-- 样式文件 -->
<link rel="stylesheet" href="css/style.css">
<!-- 图标 -->
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>📚</text></svg>">
</head>
<body>
<!-- 页面容器 -->
<div class="container">
<!-- 页面头部 -->
<header class="header">
<h1 class="title">📚 历史上的今天</h1>
<p class="subtitle">探索历史,了解今天在历史上发生的重要事件</p>
</header>
<!-- 日期信息 -->
<section class="date-section" id="date-info">
<div class="date-display">
<span class="date-text" id="date-text">加载中...</span>
</div>
</section>
<!-- 加载状态 -->
<div class="loading" id="loading">
<div class="loading-spinner"></div>
<p>正在加载历史数据...</p>
</div>
<!-- 主要内容 -->
<main class="main-content" id="history-content" style="display: none;">
<!-- 历史事件列表 -->
<section class="events-section">
<h2 class="section-title">历史事件</h2>
<div class="events-container">
<div class="events-list" id="events-list">
<!-- 事件卡片将通过 JavaScript 动态生成 -->
</div>
</div>
</section>
</main>
</div>
<!-- JavaScript 文件 -->
<script src="js/script.js"></script>
<!-- 页面性能监控 -->
<script>
// 页面加载性能监控
window.addEventListener('load', function() {
if ('performance' in window) {
const loadTime = performance.timing.loadEventEnd - performance.timing.navigationStart;
console.log(`页面加载时间: ${loadTime}ms`);
}
});
// 错误监控
window.addEventListener('error', function(event) {
console.error('页面错误:', event.error);
});
// 未处理的 Promise 错误
window.addEventListener('unhandledrejection', function(event) {
console.error('未处理的 Promise 错误:', event.reason);
});
</script>
</body>
</html>

View File

@@ -1,295 +0,0 @@
// 历史上的今天 - JavaScript 功能实现
// API 配置
const API = {
endpoints: [],
currentIndex: 0,
encoding: 'utf-8',
// 初始化API接口列表
async init() {
try {
const res = await fetch('./接口集合.json');
const endpoints = await res.json();
this.endpoints = endpoints.map(endpoint => `${endpoint}/v2/today_in_history`);
} catch (e) {
// 如果无法加载接口集合,使用默认接口
this.endpoints = ['https://60s.viki.moe/v2/today_in_history'];
}
},
// 获取当前接口URL
getCurrentUrl() {
if (this.endpoints.length === 0) return null;
const url = new URL(this.endpoints[this.currentIndex]);
url.searchParams.append('encoding', this.encoding);
return url.toString();
},
// 切换到下一个接口
switchToNext() {
this.currentIndex = (this.currentIndex + 1) % this.endpoints.length;
return this.currentIndex < this.endpoints.length;
},
// 重置到第一个接口
reset() {
this.currentIndex = 0;
}
};
// 事件类型映射
const EVENT_TYPE_MAP = {
'birth': { name: '诞生', icon: '🎂', color: '#27ae60' },
'death': { name: '逝世', icon: '🕊️', color: '#e67e22' },
'event': { name: '事件', icon: '📰', color: '#3498db' }
};
// DOM 元素
let elements = {};
let currentData = null;
// 页面加载完成后初始化
document.addEventListener('DOMContentLoaded', function() {
initElements();
loadTodayInHistory();
});
// 初始化 DOM 元素
function initElements() {
elements = {
loading: document.getElementById('loading'),
content: document.getElementById('history-content'),
dateInfo: document.getElementById('date-info'),
dateText: document.getElementById('date-text'),
totalEvents: document.getElementById('total-events'),
birthEvents: document.getElementById('birth-events'),
deathEvents: document.getElementById('death-events'),
otherEvents: document.getElementById('other-events'),
eventsList: document.getElementById('events-list')
};
}
// 加载历史上的今天数据
async function loadTodayInHistory() {
try {
showLoading(true);
// 初始化API接口列表
await API.init();
// 重置API索引到第一个接口
API.reset();
// 尝试所有API接口
for (let i = 0; i < API.endpoints.length; i++) {
try {
const url = API.getCurrentUrl();
console.log(`尝试接口 ${i + 1}/${API.endpoints.length}: ${url}`);
const response = await fetch(url, {
cache: 'no-store',
timeout: 10000 // 10秒超时
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const data = await response.json();
console.log('API响应数据:', data);
if (data.code === 200 && data.data) {
console.log(`接口 ${i + 1} 请求成功`);
currentData = data.data;
displayHistoryData(data.data);
return;
} else {
throw new Error(data.message || '获取数据失败');
}
} catch (error) {
console.warn(`接口 ${i + 1} 失败:`, error.message);
// 如果不是最后一个接口,切换到下一个
if (i < API.endpoints.length - 1) {
API.switchToNext();
continue;
}
// 所有接口都失败了,抛出错误
throw new Error('所有接口都无法访问');
}
}
} catch (error) {
console.error('加载历史数据失败:', error);
showError(`加载失败: ${error.message}`);
} finally {
showLoading(false);
}
}
// 显示历史数据
function displayHistoryData(data) {
if (!data || !data.items) {
showError('没有获取到历史数据');
return;
}
// 更新日期信息
updateDateInfo(data);
// 更新统计信息
updateStats(data.items);
// 显示事件列表
renderEventsList(data.items);
// 显示内容区域
if (elements.content) {
elements.content.classList.add('fade-in');
elements.content.style.display = 'block';
}
}
// 更新日期信息
function updateDateInfo(data) {
if (elements.dateText && data.date) {
const today = new Date();
const year = today.getFullYear();
elements.dateText.textContent = `${year}${data.month}${data.day}`;
}
}
// 更新统计信息
function updateStats(items) {
const stats = {
total: items.length,
birth: items.filter(item => item.event_type === 'birth').length,
death: items.filter(item => item.event_type === 'death').length,
event: items.filter(item => item.event_type === 'event').length
};
if (elements.totalEvents) {
elements.totalEvents.textContent = stats.total;
}
if (elements.birthEvents) {
elements.birthEvents.textContent = stats.birth;
}
if (elements.deathEvents) {
elements.deathEvents.textContent = stats.death;
}
if (elements.otherEvents) {
elements.otherEvents.textContent = stats.event;
}
}
// 渲染事件列表
function renderEventsList(items) {
if (!elements.eventsList || !items) return;
// 按年份排序(从今到古)
const sortedItems = [...items].sort((a, b) => {
return parseInt(b.year) - parseInt(a.year);
});
elements.eventsList.innerHTML = '';
sortedItems.forEach(item => {
const eventCard = createEventCard(item);
elements.eventsList.appendChild(eventCard);
});
}
// 创建事件卡片
function createEventCard(item) {
const card = document.createElement('div');
card.className = 'event-card';
const eventType = EVENT_TYPE_MAP[item.event_type] || EVENT_TYPE_MAP['event'];
card.innerHTML = `
<div class="event-type ${item.event_type}">${eventType.name}</div>
<div class="event-year">${formatYear(item.year)}</div>
<div class="event-title">${escapeHtml(item.title)}</div>
<div class="event-description">${escapeHtml(item.description)}</div>
${item.link ? `<a href="${escapeHtml(item.link)}" target="_blank" rel="noopener noreferrer" class="event-link">了解更多</a>` : ''}
`;
return card;
}
// 格式化年份显示
function formatYear(year) {
const yearNum = parseInt(year);
if (yearNum < 0) {
return `公元前${Math.abs(yearNum)}`;
} else if (yearNum < 1000) {
return `公元${yearNum}`;
} else {
return `${yearNum}`;
}
}
// 显示加载状态
function showLoading(show) {
if (elements.loading) {
elements.loading.style.display = show ? 'block' : 'none';
}
if (elements.content) {
elements.content.style.display = show ? 'none' : 'block';
}
}
// 显示错误信息
function showError(message) {
if (elements.content) {
elements.content.innerHTML = `
<div class="error">
<h3>😔 加载失败</h3>
<p>${escapeHtml(message)}</p>
<button onclick="loadTodayInHistory()" style="
margin-top: 10px;
padding: 8px 16px;
background: #667eea;
color: white;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 0.9rem;
">重新加载</button>
</div>
`;
elements.content.style.display = 'block';
}
}
// HTML 转义
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
// 错误处理
window.addEventListener('error', function(event) {
console.error('页面错误:', event.error);
});
// 网络状态监听
window.addEventListener('online', function() {
console.log('网络已连接');
});
window.addEventListener('offline', function() {
console.log('网络已断开');
showError('网络连接已断开,请检查网络设置');
});
// 导出全局方法
window.TodayInHistory = {
loadTodayInHistory,
showError,
showLoading
};

View File

@@ -1,7 +0,0 @@
[
"https://60s-cf.viki.moe",
"https://60s.viki.moe",
"https://60s.b23.run",
"https://60s.114128.xyz",
"https://60s-cf.114128.xyz"
]

View File

@@ -1,102 +0,0 @@
{
"code": 200,
"message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s反馈群 595941841",
"data": {
"date": "8-19",
"month": 8,
"day": 19,
"items": [
{
"title": "罗马帝国开国皇帝奥古斯都逝世",
"year": "14",
"description": "奥古斯都(拉丁文 Augustus的中译复数型 Augusti的原意为“神圣的”、“高贵的”带有宗教与神学式的意味。",
"event_type": "death",
"link": "https://baike.baidu.com/item/%E5%A5%A5%E5%8F%A4%E6%96%AF%E9%83%BD/14291"
},
{
"title": "近代概率论的奠基者帕斯卡逝世",
"year": "1662",
"description": "布莱士·帕斯卡Blaise Pascal 16231662是法国数学家、物理学家、哲学家、散文家。",
"event_type": "death",
"link": "https://baike.baidu.com/item/%E5%B8%83%E8%8E%B1%E5%A3%AB%C2%B7%E5%B8%95%E6%96%AF%E5%8D%A1"
},
{
"title": "瑞典国王古斯塔夫三世发动政变夺取权力",
"year": "1772",
"description": "古斯塔夫三世Gustavus III17461792是瑞典历史上褒贬最多的国王17711792。阿道夫·弗里德里克国王的儿子和继承者。",
"event_type": "event",
"link": "https://baike.baidu.com/item/%E5%8F%A4%E6%96%AF%E5%A1%94%E5%A4%AB%E4%B8%89%E4%B8%96"
},
{
"title": "美国飞机设计师奥维尔·莱特诞生",
"year": "1871",
"description": "奥威尔莱特公元1871公元1948。 奥维尔·莱特1871年生于美国俄亥俄州代顿市。上过中学但实际上未获得毕业文凭。",
"event_type": "birth",
"link": "https://baike.baidu.com/item/%E5%A5%A5%E7%BB%B4%E5%B0%94%C2%B7%E8%8E%B1%E7%89%B9"
},
{
"title": "法国著名时装设计师、香奈儿品牌创始人加布里埃·香奈儿出生",
"year": "1883",
"description": "香奈儿儿时入读修女院学校学得一手针线活。后来她与许多上流社会男士有过交往。1910年毅然放弃嫁入豪门做阔太太的她在巴黎开设了一家女装帽子店从此开创了香奈儿时尚帝国。",
"event_type": "birth",
"link": "https://baike.baidu.com/item/%E5%8A%A0%E5%B8%83%E9%87%8C%E5%9F%83%C2%B7%E9%A6%99%E5%A5%88%E5%84%BF/9480318"
},
{
"title": "美国宇航员斯托里·马斯格雷夫出生",
"year": "1935",
"description": "斯托里·马斯格雷夫Franklin Story Musgrave1935年8月19日美国宇航员拥有医学、数学、文学等六个学位入选美国国家航空航天局NASA科学家宇航员。",
"event_type": "birth",
"link": "https://baike.baidu.com/item/%E6%96%AF%E6%89%98%E9%87%8C%C2%B7%E9%A9%AC%E6%96%AF%E6%A0%BC%E9%9B%B7%E5%A4%AB"
},
{
"title": "纳粹德国陆军元帅京特·冯·克鲁格畏罪自杀",
"year": "1944",
"description": "汉斯·京特·冯·克卢格Günther·von·Kluge 1882年10月30日1944年8月19日纳粹德国陆军元帅1940.7.19),著名军事家、统帅。",
"event_type": "death",
"link": "https://baike.baidu.com/item/%E4%BA%AC%E7%89%B9%C2%B7%E5%86%AF%C2%B7%E5%85%8B%E9%B2%81%E6%A0%BC"
},
{
"title": "美国第42任总统克林顿出生",
"year": "1946",
"description": "威廉·杰斐逊·克林顿美国律师、政治家美国民主党成员曾任阿肯色州州长和第42任美国总统。克林顿基金会主席 。",
"event_type": "birth",
"link": "https://baike.baidu.com/item/%E5%A8%81%E5%BB%89%C2%B7%E6%9D%B0%E6%96%90%E9%80%8A%C2%B7%E5%85%8B%E6%9E%97%E9%A1%BF"
},
{
"title": "美国演员马修·派瑞出生",
"year": "1969",
"description": "马修·派瑞Matthew Perry1969年8月19日—2023年10月28日出生于美国马萨诸塞州普利茅斯美国、加拿大籍男演员、编剧。",
"event_type": "birth",
"link": "https://baike.baidu.com/item/%E9%A9%AC%E4%BF%AE%C2%B7%E6%B4%BE%E7%91%9E"
},
{
"title": "北回归线标志塔在广州落成",
"year": "1985",
"description": "北回归线标志塔,是标志地理学上北回归线经过地方的建筑物。",
"event_type": "event",
"link": "https://baike.baidu.com/item/%E5%8C%97%E5%9B%9E%E5%BD%92%E7%BA%BF%E6%A0%87%E5%BF%97%E5%A1%94"
},
{
"title": "“八一九事件”,苏联八月政变",
"year": "1991",
"description": "八一九事件又称“苏联政变”、“八月政变”指1991年8月19日-8月21日在苏联发生的一次政变。",
"event_type": "event",
"link": "https://baike.baidu.com/item/%E5%85%AB%E4%B8%80%E4%B9%9D%E4%BA%8B%E4%BB%B6"
},
{
"title": "量子化学家莱纳斯·卡尔·鲍林逝世",
"year": "1994",
"description": "莱纳斯·卡尔·鲍林Linus Carl Pauling1901年2月28日—1994年8月19日出生于美国俄勒冈州波特兰化学家、美国国家科学院院士、美国艺术与科学院院士1954年诺贝尔化学奖获得者。",
"event_type": "death",
"link": "https://baike.baidu.com/item/%E8%8E%B1%E7%BA%B3%E6%96%AF%C2%B7%E5%8D%A1%E5%B0%94%C2%B7%E9%B2%8D%E6%9E%97"
},
{
"title": "中国三江源自然保护区成立",
"year": "2000",
"description": "青海三江源国家级自然保护区位于青藏高原腹地青海省南部地理位置介于东经89°24102°23北纬31°3936°16之间青海三江源国家级自然保护区属湿地类型的自然保护区。",
"event_type": "event",
"link": "https://baike.baidu.com/item/%E4%B8%89%E6%B1%9F%E6%BA%90%E8%87%AA%E7%84%B6%E4%BF%9D%E6%8A%A4%E5%8C%BA"
}
]
}
}

View File

@@ -1,326 +0,0 @@
/* 必应每日壁纸 - 淡绿色清新风格样式 */
/* 重置样式 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #a8e6cf 0%, #dcedc1 50%, #ffd3a5 100%);
min-height: 100vh;
color: #2d5016;
line-height: 1.6;
overflow-x: hidden;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
/* 头部样式 */
.header {
text-align: center;
margin-bottom: 30px;
background: rgba(255, 255, 255, 0.85);
border-radius: 20px;
padding: 30px;
box-shadow: 0 8px 25px rgba(45, 80, 22, 0.08);
backdrop-filter: blur(10px);
}
.header h1 {
font-size: 2.5rem;
color: #2d5016;
margin-bottom: 10px;
font-weight: 700;
display: flex;
align-items: center;
justify-content: center;
gap: 15px;
}
.header p {
color: #5a7c65;
font-size: 1.1rem;
}
/* 加载状态 */
.loading {
text-align: center;
padding: 40px;
background: rgba(255, 255, 255, 0.85);
border-radius: 15px;
box-shadow: 0 5px 20px rgba(45, 80, 22, 0.08);
}
.spinner {
width: 40px;
height: 40px;
border: 4px solid #e8f5e8;
border-top: 4px solid #81c784;
border-radius: 50%;
animation: spin 1s linear infinite;
margin: 0 auto 20px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* 壁纸容器 */
.wallpaper-container {
background: rgba(255, 255, 255, 0.85);
border-radius: 20px;
padding: 30px;
box-shadow: 0 8px 25px rgba(45, 80, 22, 0.08);
backdrop-filter: blur(10px);
margin-bottom: 20px;
}
/* 壁纸信息 */
.wallpaper-info {
text-align: center;
margin-bottom: 25px;
}
.wallpaper-title {
font-size: 1.8rem;
font-weight: 700;
color: #2d5016;
margin-bottom: 10px;
}
.wallpaper-date {
color: #5a7c65;
font-size: 1rem;
margin-bottom: 15px;
}
.wallpaper-description {
color: #2d5016;
font-size: 1.1rem;
line-height: 1.6;
max-width: 800px;
margin: 0 auto;
}
/* 壁纸图片 */
.wallpaper-image {
position: relative;
border-radius: 15px;
overflow: hidden;
box-shadow: 0 10px 30px rgba(45, 80, 22, 0.15);
margin: 20px 0;
}
.wallpaper-image img {
width: 100%;
height: auto;
display: block;
transition: transform 0.3s ease;
}
.wallpaper-image:hover img {
transform: scale(1.02);
}
/* 下载按钮 */
.download-section {
text-align: center;
margin-top: 25px;
}
.download-btn {
background: linear-gradient(135deg, #81c784 0%, #66bb6a 100%);
color: white;
border: none;
padding: 15px 30px;
border-radius: 25px;
font-size: 1.1rem;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 4px 15px rgba(129, 199, 132, 0.3);
text-decoration: none;
display: inline-flex;
align-items: center;
gap: 10px;
}
.download-btn:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(129, 199, 132, 0.4);
}
.download-btn:active {
transform: translateY(0);
}
/* 错误提示 */
.error {
background: #fed7d7;
color: #c53030;
padding: 20px;
border-radius: 15px;
text-align: center;
border: 1px solid #feb2b2;
margin: 20px 0;
}
/* 版权信息 */
.copyright {
background: rgba(255, 255, 255, 0.7);
border-radius: 15px;
padding: 20px;
text-align: center;
color: #5a7c65;
font-size: 0.9rem;
margin-top: 20px;
}
/* 响应式设计 */
/* 平板端 */
@media (max-width: 768px) {
.container {
padding: 15px;
}
.header h1 {
font-size: 2rem;
flex-direction: column;
gap: 10px;
}
.header {
padding: 20px;
}
.wallpaper-container {
padding: 20px;
}
.wallpaper-title {
font-size: 1.5rem;
}
.wallpaper-description {
font-size: 1rem;
}
}
/* 手机端 */
@media (max-width: 480px) {
.container {
padding: 10px;
}
.header {
padding: 15px;
margin-bottom: 20px;
}
.header h1 {
font-size: 1.8rem;
}
.wallpaper-container {
padding: 15px;
}
.wallpaper-title {
font-size: 1.3rem;
}
.wallpaper-description {
font-size: 0.95rem;
}
.download-btn {
padding: 12px 25px;
font-size: 1rem;
width: 100%;
justify-content: center;
}
.copyright {
padding: 15px;
font-size: 0.8rem;
}
}
/* 大屏幕优化 */
@media (min-width: 1200px) {
.container {
padding: 40px;
}
.header {
padding: 40px;
}
.wallpaper-container {
padding: 40px;
}
.wallpaper-image {
max-height: 70vh;
overflow: hidden;
}
.wallpaper-image img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
/* 特殊效果 */
.fade-in {
animation: fadeIn 0.6s ease-in;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* 图片加载效果 */
.wallpaper-image img {
opacity: 0;
transition: opacity 0.3s ease;
}
.wallpaper-image img.loaded {
opacity: 1;
}
/* 滚动条样式 */
::-webkit-scrollbar {
width: 8px;
}
::-webkit-scrollbar-track {
background: rgba(255, 255, 255, 0.1);
}
::-webkit-scrollbar-thumb {
background: rgba(129, 199, 132, 0.5);
border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
background: rgba(129, 199, 132, 0.7);
}

View File

@@ -1,42 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="必应每日壁纸 - 每天为您呈现精美的必应壁纸">
<meta name="keywords" content="必应壁纸,每日壁纸,高清壁纸,桌面壁纸">
<title>必应每日壁纸</title>
<!-- 引入样式文件 -->
<link rel="stylesheet" href="css/style.css">
<!-- 网站图标 -->
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🖼️</text></svg>">
</head>
<body>
<div class="container">
<!-- 页面头部 -->
<header class="header">
<h1>
<span>🖼️</span>
必应每日壁纸
</h1>
<p>每天为您呈现精美的必应壁纸,发现世界之美</p>
</header>
<!-- 加载状态 -->
<div id="loading" class="loading">
<div class="spinner"></div>
<p>正在加载今日壁纸...</p>
</div>
<!-- 壁纸内容区域 -->
<main id="wallpaper-content" class="content" style="display: none;">
<!-- 壁纸内容将通过JavaScript动态加载 -->
</main>
</div>
<!-- 引入脚本文件 -->
<script src="js/script.js"></script>
</body>
</html>

View File

@@ -1,315 +0,0 @@
// 必应每日壁纸 JavaScript 功能
// API配置
const API = {
endpoints: [],
currentIndex: 0,
params: {
encoding: 'json'
},
// 初始化API接口列表
async init() {
try {
const res = await fetch('./接口集合.json');
const endpoints = await res.json();
this.endpoints = endpoints.map(endpoint => `${endpoint}/v2/bing`);
} catch (e) {
// 如果无法加载接口集合,使用默认接口
this.endpoints = ['https://60s.viki.moe/v2/bing'];
}
},
// 获取当前接口URL
getCurrentUrl() {
if (this.endpoints.length === 0) return null;
const url = new URL(this.endpoints[this.currentIndex]);
Object.keys(this.params).forEach(key => {
url.searchParams.append(key, this.params[key]);
});
return url.toString();
},
// 切换到下一个接口
switchToNext() {
this.currentIndex = (this.currentIndex + 1) % this.endpoints.length;
return this.currentIndex < this.endpoints.length;
},
// 重置到第一个接口
reset() {
this.currentIndex = 0;
}
};
// DOM元素
let elements = {};
// 初始化
document.addEventListener('DOMContentLoaded', function() {
initElements();
loadWallpaper();
});
// 初始化DOM元素
function initElements() {
elements = {
container: document.getElementById('wallpaper-content'),
loading: document.getElementById('loading')
};
}
// 加载壁纸数据
async function loadWallpaper() {
try {
showLoading(true);
// 初始化API接口列表
await API.init();
// 重置API索引到第一个接口
API.reset();
// 尝试所有API接口
for (let i = 0; i < API.endpoints.length; i++) {
try {
const url = API.getCurrentUrl();
console.log(`尝试接口 ${i + 1}/${API.endpoints.length}: ${url}`);
const response = await fetch(url, {
cache: 'no-store',
timeout: 10000 // 10秒超时
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const data = await response.json();
console.log('API响应数据:', data);
// 检查数据有效性
if (data && (data.code === 200 || data.data)) {
console.log(`接口 ${i + 1} 请求成功`);
displayWallpaper(data);
return;
}
throw new Error(data && data.message ? data.message : '接口返回异常');
} catch (error) {
console.warn(`接口 ${i + 1} 失败:`, error.message);
// 如果不是最后一个接口,切换到下一个
if (i < API.endpoints.length - 1) {
API.switchToNext();
continue;
}
// 所有接口都失败了,抛出错误
throw new Error('所有接口都无法访问');
}
}
} catch (error) {
console.error('加载壁纸失败:', error);
showError('加载壁纸失败,请稍后重试');
} finally {
showLoading(false);
}
}
// 显示壁纸
function displayWallpaper(data) {
if (!data) {
showError('没有获取到壁纸数据');
return;
}
// 提取壁纸信息
const wallpaperInfo = extractWallpaperInfo(data);
if (!wallpaperInfo || !wallpaperInfo.imageUrl) {
showError('壁纸图片链接无效');
return;
}
// 生成HTML内容
const html = generateWallpaperHTML(wallpaperInfo);
// 显示内容
elements.container.innerHTML = html;
elements.container.classList.add('fade-in');
// 绑定图片加载事件
bindImageEvents();
}
// 提取壁纸信息
function extractWallpaperInfo(data) {
// 根据API响应结构提取信息
let imageUrl = '';
let title = '必应每日壁纸';
let description = '';
let date = new Date().toLocaleDateString('zh-CN');
let copyright = '';
// 处理新的API响应格式
if (data.data) {
const wallpaperData = data.data;
title = wallpaperData.title || title;
description = wallpaperData.description || wallpaperData.main_text || '';
copyright = wallpaperData.copyright || '';
date = wallpaperData.update_date || date;
// 提取图片URL去除反引号
if (wallpaperData.cover) {
imageUrl = wallpaperData.cover.replace(/`/g, '').trim();
}
}
// 处理其他可能的API响应格式
else if (data.url) {
imageUrl = data.url;
} else if (data.image_url) {
imageUrl = data.image_url;
} else if (data.images && data.images.length > 0) {
imageUrl = data.images[0].url || data.images[0].image_url;
title = data.images[0].title || title;
description = data.images[0].description || data.images[0].copyright || '';
copyright = data.images[0].copyright || '';
}
// 如果是相对路径转换为完整URL
if (imageUrl && imageUrl.startsWith('/')) {
imageUrl = 'https://www.bing.com' + imageUrl;
}
// 确保图片URL有效
if (!imageUrl || imageUrl === '') {
console.error('无法提取图片URL原始数据:', data);
return null;
}
return {
imageUrl,
title,
description: description || copyright,
date,
copyright
};
}
// 生成壁纸HTML
function generateWallpaperHTML(info) {
return `
<div class="wallpaper-container">
<div class="wallpaper-info">
<h2 class="wallpaper-title">${escapeHtml(info.title)}</h2>
<div class="wallpaper-date">${info.date}</div>
${info.description ? `<div class="wallpaper-description">${escapeHtml(info.description)}</div>` : ''}
</div>
<div class="wallpaper-image">
<img src="${info.imageUrl}" alt="${escapeHtml(info.title)}" loading="lazy">
</div>
<div class="download-section">
<a href="${info.imageUrl}" class="download-btn" download="bing-wallpaper-${info.date}.jpg" target="_blank">
<span>📥</span>
下载壁纸
</a>
</div>
</div>
${info.copyright ? `
<div class="copyright">
<p>${escapeHtml(info.copyright)}</p>
</div>
` : ''}
`;
}
// 绑定图片事件
function bindImageEvents() {
const images = elements.container.querySelectorAll('img');
images.forEach(img => {
img.addEventListener('load', function() {
this.classList.add('loaded');
});
img.addEventListener('error', function() {
console.error('图片加载失败:', this.src);
this.parentElement.innerHTML = `
<div class="error">
<p>🖼️ 图片加载失败</p>
<p>请检查网络连接或稍后重试</p>
</div>
`;
});
});
}
// 显示/隐藏加载状态
function showLoading(show) {
if (elements.loading) {
elements.loading.style.display = show ? 'block' : 'none';
}
if (elements.container) {
elements.container.style.display = show ? 'none' : 'block';
}
}
// 显示错误信息
function showError(message) {
if (elements.container) {
elements.container.innerHTML = `
<div class="error">
<h3>⚠️ 加载失败</h3>
<p>${escapeHtml(message)}</p>
<p>请检查网络连接或稍后重试</p>
</div>
`;
elements.container.style.display = 'block';
}
}
// HTML转义
function escapeHtml(text) {
if (!text) return '';
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
// 格式化日期
function formatDate(dateString) {
try {
const date = new Date(dateString);
return date.toLocaleDateString('zh-CN', {
year: 'numeric',
month: 'long',
day: 'numeric'
});
} catch (error) {
return dateString;
}
}
// 错误处理
window.addEventListener('error', function(event) {
console.error('页面错误:', event.error);
});
// 网络状态监听
window.addEventListener('online', function() {
console.log('网络已连接');
});
window.addEventListener('offline', function() {
console.log('网络已断开');
showError('网络连接已断开,请检查网络设置');
});
// 导出函数供外部调用
window.BingWallpaper = {
loadWallpaper,
showError,
showLoading
};

View File

@@ -1,7 +0,0 @@
[
"https://60s-cf.viki.moe",
"https://60s.viki.moe",
"https://60s.b23.run",
"https://60s.114128.xyz",
"https://60s-cf.114128.xyz"
]

View File

@@ -1,15 +0,0 @@
{
"code": 200,
"message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s反馈群 595941841",
"data": {
"title": "瑟沃格湖,瓦加尔岛,法罗群岛",
"headline": "海洋上方的湖泊",
"description": "大自然自有其奇妙之处瑟沃格湖Sørvágsvatn便是其中最精彩的之一。世界湖泊日是探索法罗群岛丹麦王国的一个自治行政区这片视错觉的绝佳时机。这座位于沃格岛上的湖泊也被称为莱蒂斯湖Leitisvatn看似漂浮在海平面之上。实际上它的海拔不到100英尺。索尔瓦格斯湖是法罗群岛最大的湖泊面积约1.3平方英里为Bøsdalafossur瀑布Bøsdalafossur提供水源瀑布的湖水在那里奔腾而下最终倾泻而入大海。",
"main_text": "该湖位于瓦加尔岛南部通过Bøsdalafossur瀑布与大西洋相连形成了壮丽的“悬湖”景观。",
"cover": "https://bing.com/th?id=OHR.FaroeLake_ZH-CN3977660997_1920x1080.jpg",
"cover_4k": "https://bing.com/th?id=OHR.FaroeLake_ZH-CN3977660997_UHD.jpg",
"copyright": "© Anton Petrus/Getty Images",
"update_date": "2025-08-27 13:24:37",
"update_date_at": 1756301077809
}
}

View File

@@ -1,327 +0,0 @@
/* 每天60s读懂世界 - 清新风格样式 */
/* 重置样式 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #a8e6cf 0%, #dcedc1 50%, #ffd3a5 100%);
min-height: 100vh;
color: #2d5016;
line-height: 1.6;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
/* 头部样式 */
.header {
text-align: center;
margin-bottom: 30px;
background: rgba(255, 255, 255, 0.85);
border-radius: 20px;
padding: 30px;
box-shadow: 0 8px 25px rgba(45, 80, 22, 0.08);
backdrop-filter: blur(10px);
}
.header h1 {
font-size: 2.5rem;
color: #2d5016;
margin-bottom: 10px;
font-weight: 700;
}
.header p {
color: #5a7c65;
font-size: 1.1rem;
}
/* 控制面板 */
.controls {
background: rgba(255, 255, 255, 0.85);
border-radius: 15px;
padding: 20px;
margin-bottom: 30px;
box-shadow: 0 5px 20px rgba(45, 80, 22, 0.08);
backdrop-filter: blur(10px);
}
.date-selector {
display: flex;
align-items: center;
gap: 15px;
margin-bottom: 20px;
flex-wrap: wrap;
}
.date-selector label {
font-weight: 600;
color: #4a5568;
}
.date-selector input {
padding: 10px 15px;
border: 2px solid #e2e8f0;
border-radius: 10px;
font-size: 1rem;
transition: all 0.3s ease;
}
.date-selector input:focus {
outline: none;
border-color: #81c784;
box-shadow: 0 0 0 3px rgba(129, 199, 132, 0.1);
}
.btn {
background: linear-gradient(135deg, #81c784 0%, #66bb6a 100%);
color: white;
border: none;
padding: 12px 25px;
border-radius: 10px;
font-size: 1rem;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 4px 15px rgba(129, 199, 132, 0.3);
}
.btn:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(129, 199, 132, 0.4);
}
.btn:active {
transform: translateY(0);
}
/* 加载状态 */
.loading {
text-align: center;
padding: 40px;
background: rgba(255, 255, 255, 0.85);
border-radius: 15px;
box-shadow: 0 5px 20px rgba(45, 80, 22, 0.08);
}
.spinner {
width: 40px;
height: 40px;
border: 4px solid #e8f5e8;
border-top: 4px solid #81c784;
border-radius: 50%;
animation: spin 1s linear infinite;
margin: 0 auto 20px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* 内容区域 */
.content {
background: rgba(255, 255, 255, 0.85);
border-radius: 20px;
padding: 30px;
box-shadow: 0 8px 25px rgba(45, 80, 22, 0.08);
backdrop-filter: blur(10px);
}
.news-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 25px;
flex-wrap: wrap;
gap: 15px;
}
.news-date {
font-size: 1.5rem;
font-weight: 700;
color: #2d5016;
}
.lunar-date {
color: #5a7c65;
font-size: 1rem;
}
/* 新闻图片 */
.news-image {
width: 100%;
max-width: 600px;
height: auto;
border-radius: 15px;
margin: 20px auto;
display: block;
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
}
/* 新闻列表 */
.news-list {
margin: 25px 0;
}
.news-item {
background: #f1f8e9;
border-left: 4px solid #81c784;
padding: 15px 20px;
margin-bottom: 15px;
border-radius: 0 10px 10px 0;
transition: all 0.3s ease;
position: relative;
}
.news-item:hover {
background: #e8f5e8;
transform: translateX(5px);
box-shadow: 0 4px 15px rgba(45, 80, 22, 0.1);
}
.news-item::before {
content: counter(news-counter);
counter-increment: news-counter;
position: absolute;
left: -15px;
top: 50%;
transform: translateY(-50%);
background: #81c784;
color: white;
width: 25px;
height: 25px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 0.8rem;
font-weight: bold;
}
.news-list {
counter-reset: news-counter;
}
/* 每日一句 */
.daily-tip {
background: linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%);
padding: 20px;
border-radius: 15px;
margin: 25px 0;
text-align: center;
font-style: italic;
font-size: 1.1rem;
color: #744210;
box-shadow: 0 5px 20px rgba(252, 182, 159, 0.3);
}
/* 错误提示 */
.error {
background: #fed7d7;
color: #c53030;
padding: 20px;
border-radius: 10px;
text-align: center;
border: 1px solid #feb2b2;
}
/* 响应式设计 */
/* 平板端 */
@media (max-width: 768px) {
.container {
padding: 15px;
}
.header h1 {
font-size: 2rem;
}
.header {
padding: 20px;
}
.content {
padding: 20px;
}
.date-selector {
flex-direction: column;
align-items: stretch;
}
.news-header {
flex-direction: column;
align-items: flex-start;
}
}
/* 手机端 */
@media (max-width: 480px) {
.container {
padding: 10px;
}
.header {
padding: 15px;
margin-bottom: 20px;
}
.header h1 {
font-size: 1.8rem;
}
.controls {
padding: 15px;
}
.content {
padding: 15px;
}
.news-item {
padding: 12px 15px;
margin-left: 10px;
}
.news-item::before {
left: -10px;
width: 20px;
height: 20px;
font-size: 0.7rem;
}
.daily-tip {
padding: 15px;
font-size: 1rem;
}
.btn {
width: 100%;
padding: 15px;
}
}
/* 大屏幕优化 */
@media (min-width: 1200px) {
.container {
padding: 40px;
}
.header {
padding: 40px;
}
.content {
padding: 40px;
}
}

View File

@@ -1,49 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="每天60秒读懂世界 - 获取最新资讯,了解天下大事">
<meta name="keywords" content="新闻,资讯,每日新闻,60秒读懂世界">
<title>每天60秒读懂世界 | 最新资讯</title>
<!-- 引入CSS样式 -->
<link rel="stylesheet" href="css/style.css">
<!-- 网站图标 -->
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>📰</text></svg>">
<!-- Open Graph 元数据 -->
<meta property="og:title" content="每天60秒读懂世界">
<meta property="og:description" content="获取最新资讯,了解天下大事">
<meta property="og:type" content="website">
</head>
<body>
<div class="container">
<!-- 页面头部 -->
<header class="header">
<h1>📰 每天60秒读懂世界</h1>
<p>获取最新资讯,了解天下大事</p>
</header>
<!-- 主要内容区域 -->
<main id="content" class="content">
<!-- 内容将通过JavaScript动态加载 -->
<div class="loading">
<div class="spinner"></div>
<p>正在加载今日资讯...</p>
</div>
</main>
</div>
<!-- 页面底部 -->
<footer style="text-align: center; padding: 20px; color: rgba(255,255,255,0.8); font-size: 0.9rem;">
<p>Made with ❤️ | 数据来源每天60秒读懂世界API</p>
</footer>
<!-- 引入JavaScript -->
<script src="js/script.js"></script>
</body>
</html>

View File

@@ -1,305 +0,0 @@
// 每天60s读懂世界 - JavaScript功能实现
const API = {
endpoints: [],
currentIndex: 0,
params: {
encoding: 'json'
},
localFallback: '返回接口.json',
// 初始化API接口列表
async init() {
try {
const res = await fetch('./接口集合.json');
const endpoints = await res.json();
this.endpoints = endpoints.map(endpoint => `${endpoint}/v2/60s`);
} catch (e) {
// 如果无法加载接口集合,使用默认接口
this.endpoints = ['https://60s.viki.moe/v2/60s'];
}
},
// 获取当前接口URL
getCurrentUrl() {
if (this.endpoints.length === 0) return null;
const url = new URL(this.endpoints[this.currentIndex]);
Object.entries(this.params).forEach(([k, v]) => url.searchParams.append(k, v));
return url.toString();
},
// 切换到下一个接口
switchToNext() {
this.currentIndex = (this.currentIndex + 1) % this.endpoints.length;
return this.currentIndex < this.endpoints.length;
},
// 重置到第一个接口
reset() {
this.currentIndex = 0;
}
};
class NewsApp {
constructor() {
this.apiUrl = 'https://60s.viki.moe/v2/60s';
this.init();
}
init() {
this.bindEvents();
this.loadTodayNews();
}
bindEvents() {
// 移除了刷新按钮,不需要绑定事件
}
formatDate(date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
}
showLoading() {
const contentDiv = document.getElementById('content');
if (contentDiv) {
contentDiv.innerHTML = `
<div class="loading">
<div class="spinner"></div>
<p>正在获取最新资讯...</p>
</div>
`;
}
}
showError(message) {
const contentDiv = document.getElementById('content');
if (contentDiv) {
contentDiv.innerHTML = `
<div class="error">
<h3>😔 获取失败</h3>
<p>${message}</p>
</div>
`;
}
}
async loadNews() {
try {
this.showLoading();
// 尝试从API获取数据
let data = await this.fetchFromAPI();
// 如果API失败尝试本地数据
if (!data) {
data = await this.fetchFromLocal();
}
if (!data) {
throw new Error('无法获取数据,请检查网络连接或稍后重试');
}
if (data.code !== 200) {
throw new Error(data.message || '获取数据失败');
}
this.renderNews(data.data);
} catch (error) {
console.error('获取新闻失败:', error);
this.showError(error.message || '网络连接失败,请检查网络后重试');
}
}
async fetchFromAPI() {
// 初始化API接口列表
await API.init();
// 重置API索引到第一个接口
API.reset();
// 尝试所有API接口
for (let i = 0; i < API.endpoints.length; i++) {
try {
const url = API.getCurrentUrl();
console.log(`尝试接口 ${i + 1}/${API.endpoints.length}: ${url}`);
const resp = await fetch(url, {
cache: 'no-store'
});
if (!resp.ok) {
throw new Error(`HTTP ${resp.status}: ${resp.statusText}`);
}
const data = await resp.json();
if (data && data.code === 200) {
console.log(`接口 ${i + 1} 请求成功`);
return data;
}
throw new Error(data && data.message ? data.message : '接口返回异常');
} catch (e) {
console.warn(`接口 ${i + 1} 失败:`, e.message);
// 如果不是最后一个接口,切换到下一个
if (i < API.endpoints.length - 1) {
API.switchToNext();
continue;
}
// 所有接口都失败了
console.warn('所有远程接口都失败,尝试本地数据');
return null;
}
}
}
async fetchFromLocal() {
try {
const resp = await fetch(API.localFallback + `?t=${Date.now()}`);
if (!resp.ok) throw new Error(`本地文件HTTP ${resp.status}`);
const data = await resp.json();
return data;
} catch (e) {
console.error('读取本地返回接口.json失败:', e);
return null;
}
}
loadTodayNews() {
this.loadNews();
}
renderNews(newsData) {
const contentDiv = document.getElementById('content');
if (!contentDiv || !newsData) return;
const {
date,
day_of_week,
lunar_date,
news,
tip,
link
} = newsData;
let newsListHtml = '';
if (news && news.length > 0) {
newsListHtml = news.map(item => `
<div class="news-item">
${this.escapeHtml(item)}
</div>
`).join('');
}
// 移除图片显示功能
const tipHtml = tip ? `
<div class="daily-tip">
💡 ${this.escapeHtml(tip)}
</div>
` : '';
const linkHtml = link ? `
<div style="text-align: center; margin-top: 20px;">
<a href="${this.escapeHtml(link)}" target="_blank" class="btn" style="text-decoration: none; display: inline-block;">
📖 查看原文
</a>
</div>
` : '';
contentDiv.innerHTML = `
<div class="news-header">
<div>
<div class="news-date">${this.escapeHtml(date)} ${this.escapeHtml(day_of_week || '')}</div>
${lunar_date ? `<div class="lunar-date">${this.escapeHtml(lunar_date)}</div>` : ''}
</div>
</div>
${tipHtml}
<div class="news-list">
<h3 style="margin-bottom: 20px; color: #2d5016; font-size: 1.3rem;">📰 今日要闻</h3>
${newsListHtml}
</div>
${linkHtml}
<div style="text-align: center; margin-top: 30px; color: #5a7c65; font-size: 0.9rem;">
<p>数据来源每天60秒读懂世界</p>
<p>更新时间:${newsData.api_updated || '未知'}</p>
</div>
`;
}
escapeHtml(text) {
if (typeof text !== 'string') return text;
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
}
// 页面加载完成后初始化应用
document.addEventListener('DOMContentLoaded', function() {
window.newsApp = new NewsApp();
});
// 添加一些实用功能
function copyToClipboard(text) {
navigator.clipboard.writeText(text).then(() => {
showToast('已复制到剪贴板');
}).catch(() => {
showToast('复制失败,请手动复制');
});
}
function showToast(message) {
// 创建提示框
const toast = document.createElement('div');
toast.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
background: #4a5568;
color: white;
padding: 12px 20px;
border-radius: 8px;
z-index: 1000;
font-size: 14px;
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
animation: slideIn 0.3s ease;
`;
toast.textContent = message;
// 添加动画样式
const style = document.createElement('style');
style.textContent = `
@keyframes slideIn {
from { transform: translateX(100%); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
`;
document.head.appendChild(style);
document.body.appendChild(toast);
// 3秒后自动移除
setTimeout(() => {
toast.remove();
style.remove();
}, 3000);
}
// 添加键盘快捷键支持
document.addEventListener('keydown', function(e) {
// Ctrl/Cmd + R 刷新数据
if ((e.ctrlKey || e.metaKey) && e.key === 'r') {
e.preventDefault();
if (window.newsApp) {
window.newsApp.loadNews();
}
}
});

View File

@@ -1,7 +0,0 @@
[
"https://60s-cf.viki.moe",
"https://60s.viki.moe",
"https://60s.b23.run",
"https://60s.114128.xyz",
"https://60s-cf.114128.xyz"
]

View File

@@ -1,66 +0,0 @@
{
"code": 200,
"message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s反馈群 595941841",
"data": [
{
"id": "9aa227e2ba294bb1a95c95fde892eb31",
"title": "《Totally Reliable Delivery Service》 Standard Edition",
"cover": "https://cdn1.epicgames.com/52b90f9a982a404781b189f6a7903226/offer/EGS_TotallyReliableDeliveryService_WereFiveGames_S1-2560x1440-47e6e9562d62705a75ea7b7096d0b8dc.jpg",
"original_price": 52,
"original_price_desc": "¥52.00",
"description": "穿好护腰护具发动货车送货的时间到啦在一个高度互动的沙盒世界中与最多三位好友一起随意地完成送货。货物已试投这就是我们靠谱快递Totally Reliable Delivery Service的品质保证",
"seller": "Infogrames LLC",
"is_free_now": true,
"free_start": "2025/08/14 23:00:00",
"free_start_at": 1755183600000,
"free_end": "2025/08/21 23:00:00",
"free_end_at": 1755788400000,
"link": "https://store.epicgames.com/store/zh-CN/p/totally-reliable-delivery-service/home"
},
{
"id": "8ea3500dc38e4f429702bf889c172d3d",
"title": "Hidden Folks",
"cover": "https://cdn1.epicgames.com/spt-assets/7bfd56b0586348dcb139945d9e59f988/hidden-folks-1b7hh.png",
"original_price": 47,
"original_price_desc": "¥47.00",
"description": "Search for hidden folks in hand-drawn, interactive, miniature landscapes. Unfurl tent flaps, cut through bushes, slam doors, and poke some crocodiles! Rooooaaaarrrr!!!!!",
"seller": "Adriaan de Jongh",
"is_free_now": true,
"free_start": "2025/08/14 23:00:00",
"free_start_at": 1755183600000,
"free_end": "2025/08/21 23:00:00",
"free_end_at": 1755788400000,
"link": "https://store.epicgames.com/store/zh-CN/p/hidden-folks-239d16"
},
{
"id": "4cbb6c3704d240f19c3dd5f5cb2b0cb4",
"title": "Kamaeru",
"cover": "https://cdn1.epicgames.com/spt-assets/44313cfbb62b4df5801d0c8d541c2624/kamaeru-40asc.png",
"original_price": 62,
"original_price_desc": "¥62.00",
"description": "Foster a sanctuary for frogs and restore the biodiversity of the wetlands in Kamaeru, a cozy frog collecting game, where you take pictures of frogs, play mini-games and decorate your habitat. Hop right to it!",
"seller": "Armor Games Studios",
"is_free_now": false,
"free_start": "2025/08/21 23:00:00",
"free_start_at": 1755788400000,
"free_end": "2025/08/28 23:00:00",
"free_end_at": 1756393200000,
"link": "https://store.epicgames.com/store/zh-CN/p/kamaeru-0c301e"
},
{
"id": "0d9a533f0e684cc18620a8f408e8e72c",
"title": "Strange Horticulture",
"cover": "https://cdn1.epicgames.com/spt-assets/15e8e3eba65a4763a815d6eae1d763b2/strange-horticulture-offer-2wghv.png",
"original_price": 45,
"original_price_desc": "¥45.00",
"description": "款神秘学解谜游戏,你将扮演当地植物商店的店主,寻找并识别新的植物,悠闲撸猫,与女巫团体交谈,或加入异教。收集各种强大的植物,用它们来影响故事走向,揭开昂德米尔镇的黑暗谜团。",
"seller": "Iceberg Interactive",
"is_free_now": false,
"free_start": "2025/08/21 23:00:00",
"free_start_at": 1755788400000,
"free_end": "2025/08/28 23:00:00",
"free_end_at": 1756393200000,
"link": "https://store.epicgames.com/store/zh-CN/p/strange-horticulture-360e80"
}
]
}

View File

@@ -1,409 +0,0 @@
/* 每日国际汇率 - 淡绿色清新风格样式 */
/* 重置样式 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #a8e6cf 0%, #dcedc1 50%, #ffd3a5 100%);
min-height: 100vh;
color: #2d5016;
line-height: 1.6;
overflow-x: hidden;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
/* 头部样式 */
.header {
text-align: center;
margin-bottom: 30px;
background: rgba(255, 255, 255, 0.85);
border-radius: 20px;
padding: 30px;
box-shadow: 0 8px 25px rgba(45, 80, 22, 0.08);
backdrop-filter: blur(10px);
}
.header h1 {
font-size: 2.5rem;
color: #2d5016;
margin-bottom: 10px;
font-weight: 700;
display: flex;
align-items: center;
justify-content: center;
gap: 15px;
}
.header p {
color: #5a7c65;
font-size: 1.1rem;
}
/* 货币选择器 */
.currency-selector {
background: rgba(255, 255, 255, 0.85);
border-radius: 15px;
padding: 20px;
margin-bottom: 20px;
box-shadow: 0 5px 20px rgba(45, 80, 22, 0.08);
text-align: center;
}
.currency-selector label {
display: block;
margin-bottom: 10px;
font-weight: 600;
color: #2d5016;
}
.currency-selector select {
padding: 12px 20px;
border: 2px solid #c8e6c9;
border-radius: 25px;
background: white;
color: #2d5016;
font-size: 1rem;
min-width: 200px;
cursor: pointer;
transition: all 0.3s ease;
}
.currency-selector select:focus {
outline: none;
border-color: #81c784;
box-shadow: 0 0 0 3px rgba(129, 199, 132, 0.2);
}
/* 加载状态 */
.loading {
text-align: center;
padding: 40px;
background: rgba(255, 255, 255, 0.85);
border-radius: 15px;
box-shadow: 0 5px 20px rgba(45, 80, 22, 0.08);
}
.spinner {
width: 40px;
height: 40px;
border: 4px solid #e8f5e8;
border-top: 4px solid #81c784;
border-radius: 50%;
animation: spin 1s linear infinite;
margin: 0 auto 20px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* 汇率信息容器 */
.exchange-info {
background: rgba(255, 255, 255, 0.85);
border-radius: 20px;
padding: 25px;
margin-bottom: 20px;
box-shadow: 0 8px 25px rgba(45, 80, 22, 0.08);
backdrop-filter: blur(10px);
}
.base-currency {
text-align: center;
margin-bottom: 20px;
}
.base-currency h2 {
font-size: 1.8rem;
color: #2d5016;
margin-bottom: 10px;
}
.update-time {
color: #5a7c65;
font-size: 0.9rem;
}
/* 汇率网格 */
.rates-grid {
display: grid;
grid-template-columns: repeat(8, 1fr);
gap: 10px;
margin-top: 20px;
}
.rate-card {
background: rgba(255, 255, 255, 0.9);
border-radius: 10px;
padding: 12px;
box-shadow: 0 3px 10px rgba(45, 80, 22, 0.06);
transition: all 0.3s ease;
border: 1px solid rgba(200, 230, 201, 0.5);
text-align: center;
}
.rate-card:hover {
transform: translateY(-1px);
box-shadow: 0 4px 15px rgba(45, 80, 22, 0.1);
border-color: #81c784;
}
.currency-code {
font-size: 1rem;
font-weight: 700;
color: #2d5016;
margin-bottom: 6px;
display: flex;
align-items: center;
justify-content: center;
gap: 6px;
}
.currency-flag {
font-size: 1.2rem;
}
.exchange-rate {
font-size: 1.1rem;
font-weight: 600;
color: #388e3c;
margin-bottom: 4px;
}
.currency-name {
color: #5a7c65;
font-size: 0.8rem;
line-height: 1.2;
}
/* 搜索框 */
.search-container {
background: rgba(255, 255, 255, 0.85);
border-radius: 15px;
padding: 20px;
margin-bottom: 20px;
box-shadow: 0 5px 20px rgba(45, 80, 22, 0.08);
}
.search-input {
width: 100%;
padding: 12px 20px;
border: 2px solid #c8e6c9;
border-radius: 25px;
background: white;
color: #2d5016;
font-size: 1rem;
transition: all 0.3s ease;
}
.search-input:focus {
outline: none;
border-color: #81c784;
box-shadow: 0 0 0 3px rgba(129, 199, 132, 0.2);
}
.search-input::placeholder {
color: #81c784;
}
/* 错误提示 */
.error {
background: #fed7d7;
color: #c53030;
padding: 20px;
border-radius: 15px;
text-align: center;
border: 1px solid #feb2b2;
margin: 20px 0;
}
/* 统计信息 */
.stats {
background: rgba(255, 255, 255, 0.85);
border-radius: 15px;
padding: 20px;
margin-bottom: 20px;
box-shadow: 0 5px 20px rgba(45, 80, 22, 0.08);
text-align: center;
}
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 20px;
margin-top: 15px;
}
.stat-item {
padding: 15px;
background: rgba(129, 199, 132, 0.1);
border-radius: 10px;
}
.stat-number {
font-size: 1.5rem;
font-weight: 700;
color: #2d5016;
}
.stat-label {
color: #5a7c65;
font-size: 0.9rem;
margin-top: 5px;
}
/* 响应式设计 */
/* 平板端 */
@media (max-width: 768px) and (min-width: 481px) {
.container {
padding: 15px;
}
.header h1 {
font-size: 2rem;
flex-direction: column;
gap: 10px;
}
.header {
padding: 20px;
}
.rates-grid {
grid-template-columns: repeat(6, 1fr);
gap: 8px;
}
.rate-card {
padding: 10px;
}
.currency-selector select {
min-width: 180px;
}
}
/* 手机端 */
@media (max-width: 480px) {
.container {
padding: 10px;
}
.header {
padding: 15px;
margin-bottom: 20px;
}
.header h1 {
font-size: 1.8rem;
}
.rates-grid {
grid-template-columns: repeat(4, 1fr);
gap: 6px;
}
.rate-card {
padding: 8px;
border-radius: 8px;
}
.currency-code {
font-size: 0.85rem;
margin-bottom: 4px;
gap: 4px;
}
.currency-flag {
font-size: 1rem;
}
.exchange-rate {
font-size: 0.9rem;
margin-bottom: 3px;
}
.currency-name {
font-size: 0.7rem;
line-height: 1.1;
}
.currency-selector {
padding: 15px;
}
.currency-selector select {
min-width: 100%;
padding: 10px 15px;
}
.search-input {
padding: 10px 15px;
}
.stats-grid {
grid-template-columns: repeat(2, 1fr);
gap: 10px;
}
}
/* 大屏幕优化 */
@media (min-width: 1200px) {
.container {
padding: 40px;
}
.header {
padding: 40px;
}
}
/* 特殊效果 */
.fade-in {
animation: fadeIn 0.6s ease-in;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* 滚动条样式 */
::-webkit-scrollbar {
width: 8px;
}
::-webkit-scrollbar-track {
background: rgba(255, 255, 255, 0.1);
}
::-webkit-scrollbar-thumb {
background: rgba(129, 199, 132, 0.5);
border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
background: rgba(129, 199, 132, 0.7);
}
/* 隐藏类 */
.hidden {
display: none;
}

View File

@@ -1,86 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="每日国际汇率 - 实时获取全球货币汇率信息">
<meta name="keywords" content="汇率,外汇,货币,汇率查询,实时汇率">
<title>每日国际汇率</title>
<!-- 引入样式文件 -->
<link rel="stylesheet" href="css/style.css">
<!-- 网站图标 -->
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>💱</text></svg>">
</head>
<body>
<div class="container">
<!-- 页面头部 -->
<header class="header">
<h1>
<span>💱</span>
每日国际汇率
</h1>
<p>实时获取全球货币汇率信息,助您掌握汇率动态</p>
</header>
<!-- 货币选择器 -->
<div class="currency-selector">
<label for="currency-select">选择基础货币:</label>
<select id="currency-select">
<!-- 货币选项将通过JavaScript动态生成 -->
</select>
</div>
<!-- 搜索框 -->
<div class="search-container">
<input
type="text"
id="search-input"
class="search-input"
placeholder="🔍 搜索货币代码或名称..."
>
</div>
<!-- 加载状态 -->
<div id="loading" class="loading">
<div class="spinner"></div>
<p>正在加载汇率数据...</p>
</div>
<!-- 汇率内容区域 -->
<main id="exchange-content" class="content" style="display: none;">
<!-- 汇率信息 -->
<div class="exchange-info">
<div class="base-currency">
<h2 id="base-currency">基础货币</h2>
<div id="update-time" class="update-time">更新时间: --</div>
</div>
<!-- 统计信息 -->
<div class="stats">
<h3>汇率统计</h3>
<div class="stats-grid">
<div class="stat-item">
<div id="total-currencies" class="stat-number">--</div>
<div class="stat-label">货币总数</div>
</div>
<div class="stat-item">
<div id="last-update" class="stat-number">--</div>
<div class="stat-label">最后更新</div>
</div>
</div>
</div>
<!-- 汇率网格 -->
<div id="rates-grid" class="rates-grid">
<!-- 汇率卡片将通过JavaScript动态生成 -->
</div>
</div>
</main>
</div>
<!-- 引入脚本文件 -->
<script src="js/script.js"></script>
</body>
</html>

View File

@@ -1,520 +0,0 @@
// 每日国际汇率 JavaScript 功能
// API配置
const API = {
endpoints: [],
currentIndex: 0,
defaultCurrency: 'CNY',
localFallback: '返回接口.json',
// 初始化API接口列表
async init() {
try {
const res = await fetch('./接口集合.json');
const endpoints = await res.json();
this.endpoints = endpoints.map(endpoint => `${endpoint}/v2/exchange_rate`);
} catch (e) {
// 如果无法加载接口集合,使用默认接口
this.endpoints = ['https://60s.viki.moe/v2/exchange_rate'];
}
},
// 获取当前接口URL
getCurrentUrl(currency) {
if (this.endpoints.length === 0) return null;
const url = new URL(this.endpoints[this.currentIndex]);
url.searchParams.append('currency', currency);
return url.toString();
},
// 切换到下一个接口
switchToNext() {
this.currentIndex = (this.currentIndex + 1) % this.endpoints.length;
return this.currentIndex < this.endpoints.length;
},
// 重置到第一个接口
reset() {
this.currentIndex = 0;
}
};
// 常用货币列表
const POPULAR_CURRENCIES = [
{ code: 'CNY', name: '人民币', flag: '🇨🇳' },
{ code: 'USD', name: '美元', flag: '🇺🇸' },
{ code: 'EUR', name: '欧元', flag: '🇪🇺' },
{ code: 'JPY', name: '日元', flag: '🇯🇵' },
{ code: 'GBP', name: '英镑', flag: '🇬🇧' },
{ code: 'AUD', name: '澳元', flag: '🇦🇺' },
{ code: 'CAD', name: '加元', flag: '🇨🇦' },
{ code: 'CHF', name: '瑞士法郎', flag: '🇨🇭' },
{ code: 'HKD', name: '港币', flag: '🇭🇰' },
{ code: 'SGD', name: '新加坡元', flag: '🇸🇬' },
{ code: 'KRW', name: '韩元', flag: '🇰🇷' },
{ code: 'THB', name: '泰铢', flag: '🇹🇭' }
];
// 货币优先级排序 - 经济发达、交易频繁的国家货币优先
const CURRENCY_PRIORITY = {
// 第一梯队:全球主要储备货币和交易货币
'USD': 1, // 美元 - 全球储备货币
'EUR': 2, // 欧元 - 欧盟统一货币
'JPY': 3, // 日元 - 亚洲主要货币
'GBP': 4, // 英镑 - 传统储备货币
'CNY': 5, // 人民币 - 中国货币
// 第二梯队:发达国家货币
'CHF': 10, // 瑞士法郎 - 避险货币
'CAD': 11, // 加拿大元
'AUD': 12, // 澳大利亚元
'NZD': 13, // 新西兰元
'SEK': 14, // 瑞典克朗
'NOK': 15, // 挪威克朗
'DKK': 16, // 丹麦克朗
// 第三梯队:亚洲发达经济体
'HKD': 20, // 港币
'SGD': 21, // 新加坡元
'KRW': 22, // 韩元
'TWD': 23, // 新台币
// 第四梯队:重要新兴市场货币
'RUB': 30, // 俄罗斯卢布
'INR': 31, // 印度卢比
'BRL': 32, // 巴西雷亚尔
'MXN': 33, // 墨西哥比索
'ZAR': 34, // 南非兰特
'TRY': 35, // 土耳其里拉
// 第五梯队:亚洲重要货币
'THB': 40, // 泰铢
'MYR': 41, // 马来西亚林吉特
'IDR': 42, // 印尼盾
'PHP': 43, // 菲律宾比索
'VND': 44, // 越南盾
// 第六梯队:中东石油国家货币
'SAR': 50, // 沙特里亚尔
'AED': 51, // 阿联酋迪拉姆
'QAR': 52, // 卡塔尔里亚尔
'KWD': 53, // 科威特第纳尔
// 第七梯队:欧洲其他货币
'PLN': 60, // 波兰兹罗提
'CZK': 61, // 捷克克朗
'HUF': 62, // 匈牙利福林
'RON': 63, // 罗马尼亚列伊
'BGN': 64, // 保加利亚列弗
'HRK': 65, // 克罗地亚库纳
// 第八梯队:拉美货币
'ARS': 70, // 阿根廷比索
'CLP': 71, // 智利比索
'COP': 72, // 哥伦比亚比索
'PEN': 73, // 秘鲁索尔
'UYU': 74, // 乌拉圭比索
// 其他货币默认优先级为 999
};
// 货币名称映射
const CURRENCY_NAMES = {
'CNY': '人民币', 'USD': '美元', 'EUR': '欧元', 'JPY': '日元', 'GBP': '英镑',
'AUD': '澳元', 'CAD': '加元', 'CHF': '瑞士法郎', 'HKD': '港币', 'SGD': '新加坡元',
'KRW': '韩元', 'THB': '泰铢', 'AED': '阿联酋迪拉姆', 'AFN': '阿富汗尼',
'ALL': '阿尔巴尼亚列克', 'AMD': '亚美尼亚德拉姆', 'ANG': '荷属安的列斯盾',
'AOA': '安哥拉宽扎', 'ARS': '阿根廷比索', 'AWG': '阿鲁巴弗罗林',
'AZN': '阿塞拜疆马纳特', 'BAM': '波黑马克', 'BBD': '巴巴多斯元',
'BDT': '孟加拉塔卡', 'BGN': '保加利亚列弗', 'BHD': '巴林第纳尔',
'BIF': '布隆迪法郎', 'BMD': '百慕大元', 'BND': '文莱元', 'BOB': '玻利维亚诺',
'BRL': '巴西雷亚尔', 'BSD': '巴哈马元', 'BTN': '不丹努尔特鲁姆',
'BWP': '博茨瓦纳普拉', 'BYN': '白俄罗斯卢布', 'BZD': '伯利兹元',
'CDF': '刚果法郎', 'CLP': '智利比索', 'COP': '哥伦比亚比索', 'CRC': '哥斯达黎加科朗',
'CUP': '古巴比索', 'CVE': '佛得角埃斯库多', 'CZK': '捷克克朗', 'DJF': '吉布提法郎',
'DKK': '丹麦克朗', 'DOP': '多米尼加比索', 'DZD': '阿尔及利亚第纳尔', 'EGP': '埃及镑',
'ERN': '厄立特里亚纳克法', 'ETB': '埃塞俄比亚比尔', 'FJD': '斐济元', 'FKP': '福克兰群岛镑',
'FOK': '法罗群岛克朗', 'GEL': '格鲁吉亚拉里', 'GGP': '根西岛镑', 'GHS': '加纳塞地',
'GIP': '直布罗陀镑', 'GMD': '冈比亚达拉西', 'GNF': '几内亚法郎', 'GTQ': '危地马拉格查尔',
'GYD': '圭亚那元', 'HNL': '洪都拉斯伦皮拉', 'HRK': '克罗地亚库纳', 'HTG': '海地古德',
'HUF': '匈牙利福林', 'IDR': '印尼盾', 'ILS': '以色列新谢克尔', 'IMP': '马恩岛镑',
'INR': '印度卢比', 'IQD': '伊拉克第纳尔', 'IRR': '伊朗里亚尔', 'ISK': '冰岛克朗',
'JEP': '泽西岛镑', 'JMD': '牙买加元', 'JOD': '约旦第纳尔', 'KES': '肯尼亚先令',
'KGS': '吉尔吉斯斯坦索姆', 'KHR': '柬埔寨瑞尔', 'KID': '基里巴斯元', 'KMF': '科摩罗法郎',
'KWD': '科威特第纳尔', 'KYD': '开曼群岛元', 'KZT': '哈萨克斯坦坚戈', 'LAK': '老挝基普',
'LBP': '黎巴嫩镑', 'LKR': '斯里兰卡卢比', 'LRD': '利比里亚元', 'LSL': '莱索托洛蒂',
'LYD': '利比亚第纳尔', 'MAD': '摩洛哥迪拉姆', 'MDL': '摩尔多瓦列伊', 'MGA': '马达加斯加阿里亚里',
'MKD': '北马其顿第纳尔', 'MMK': '缅甸缅元', 'MNT': '蒙古图格里克', 'MOP': '澳门帕塔卡',
'MRU': '毛里塔尼亚乌吉亚', 'MUR': '毛里求斯卢比', 'MVR': '马尔代夫拉菲亚', 'MWK': '马拉维克瓦查',
'MXN': '墨西哥比索', 'MYR': '马来西亚林吉特', 'MZN': '莫桑比克梅蒂卡尔', 'NAD': '纳米比亚元',
'NGN': '尼日利亚奈拉', 'NIO': '尼加拉瓜科多巴', 'NOK': '挪威克朗', 'NPR': '尼泊尔卢比',
'NZD': '新西兰元', 'OMR': '阿曼里亚尔', 'PAB': '巴拿马巴波亚', 'PEN': '秘鲁索尔',
'PGK': '巴布亚新几内亚基那', 'PHP': '菲律宾比索', 'PKR': '巴基斯坦卢比', 'PLN': '波兰兹罗提',
'PYG': '巴拉圭瓜拉尼', 'QAR': '卡塔尔里亚尔', 'RON': '罗马尼亚列伊', 'RSD': '塞尔维亚第纳尔',
'RUB': '俄罗斯卢布', 'RWF': '卢旺达法郎', 'SAR': '沙特里亚尔', 'SBD': '所罗门群岛元',
'SCR': '塞舌尔卢比', 'SDG': '苏丹镑', 'SEK': '瑞典克朗', 'SHP': '圣赫勒拿镑',
'SLE': '塞拉利昂利昂', 'SLL': '塞拉利昂利昂(旧)', 'SOS': '索马里先令', 'SRD': '苏里南元',
'SSP': '南苏丹镑', 'STN': '圣多美和普林西比多布拉', 'SYP': '叙利亚镑', 'SZL': '斯威士兰里兰吉尼',
'TJS': '塔吉克斯坦索莫尼', 'TMT': '土库曼斯坦马纳特', 'TND': '突尼斯第纳尔', 'TOP': '汤加潘加',
'TRY': '土耳其里拉', 'TTD': '特立尼达和多巴哥元', 'TVD': '图瓦卢元', 'TWD': '新台币',
'TZS': '坦桑尼亚先令', 'UAH': '乌克兰格里夫纳', 'UGX': '乌干达先令', 'UYU': '乌拉圭比索',
'UZS': '乌兹别克斯坦苏姆', 'VES': '委内瑞拉玻利瓦尔', 'VND': '越南盾', 'VUV': '瓦努阿图瓦图',
'WST': '萨摩亚塔拉', 'XAF': '中非法郎', 'XCD': '东加勒比元', 'XCG': '加勒比盾',
'XDR': '特别提款权', 'XOF': '西非法郎', 'XPF': '太平洋法郎', 'YER': '也门里亚尔',
'ZAR': '南非兰特', 'ZMW': '赞比亚克瓦查', 'ZWL': '津巴布韦元'
};
// 货币旗帜映射
const CURRENCY_FLAGS = {
'CNY': '🇨🇳', 'USD': '🇺🇸', 'EUR': '🇪🇺', 'JPY': '🇯🇵', 'GBP': '🇬🇧',
'AUD': '🇦🇺', 'CAD': '🇨🇦', 'CHF': '🇨🇭', 'HKD': '🇭🇰', 'SGD': '🇸🇬',
'KRW': '🇰🇷', 'THB': '🇹🇭', 'AED': '🇦🇪', 'AFN': '🇦🇫', 'ALL': '🇦🇱',
'AMD': '🇦🇲', 'ANG': '🇳🇱', 'AOA': '🇦🇴', 'ARS': '🇦🇷', 'AWG': '🇦🇼',
'AZN': '🇦🇿', 'BAM': '🇧🇦', 'BBD': '🇧🇧', 'BDT': '🇧🇩', 'BGN': '🇧🇬',
'BHD': '🇧🇭', 'BIF': '🇧🇮', 'BMD': '🇧🇲', 'BND': '🇧🇳', 'BOB': '🇧🇴',
'BRL': '🇧🇷', 'BSD': '🇧🇸', 'BTN': '🇧🇹', 'BWP': '🇧🇼', 'BYN': '🇧🇾',
'BZD': '🇧🇿', 'CDF': '🇨🇩', 'CLP': '🇨🇱', 'COP': '🇨🇴', 'CRC': '🇨🇷',
'CUP': '🇨🇺', 'CVE': '🇨🇻', 'CZK': '🇨🇿', 'DJF': '🇩🇯', 'DKK': '🇩🇰',
'DOP': '🇩🇴', 'DZD': '🇩🇿', 'EGP': '🇪🇬', 'ERN': '🇪🇷', 'ETB': '🇪🇹',
'FJD': '🇫🇯', 'FKP': '🇫🇰', 'FOK': '🇫🇴', 'GEL': '🇬🇪', 'GGP': '🇬🇬',
'GHS': '🇬🇭', 'GIP': '🇬🇮', 'GMD': '🇬🇲', 'GNF': '🇬🇳', 'GTQ': '🇬🇹',
'GYD': '🇬🇾', 'HNL': '🇭🇳', 'HRK': '🇭🇷', 'HTG': '🇭🇹', 'HUF': '🇭🇺',
'IDR': '🇮🇩', 'ILS': '🇮🇱', 'IMP': '🇮🇲', 'INR': '🇮🇳', 'IQD': '🇮🇶',
'IRR': '🇮🇷', 'ISK': '🇮🇸', 'JEP': '🇯🇪', 'JMD': '🇯🇲', 'JOD': '🇯🇴',
'KES': '🇰🇪', 'KGS': '🇰🇬', 'KHR': '🇰🇭', 'KID': '🇰🇮', 'KMF': '🇰🇲',
'KWD': '🇰🇼', 'KYD': '🇰🇾', 'KZT': '🇰🇿', 'LAK': '🇱🇦', 'LBP': '🇱🇧',
'LKR': '🇱🇰', 'LRD': '🇱🇷', 'LSL': '🇱🇸', 'LYD': '🇱🇾', 'MAD': '🇲🇦',
'MDL': '🇲🇩', 'MGA': '🇲🇬', 'MKD': '🇲🇰', 'MMK': '🇲🇲', 'MNT': '🇲🇳',
'MOP': '🇲🇴', 'MRU': '🇲🇷', 'MUR': '🇲🇺', 'MVR': '🇲🇻', 'MWK': '🇲🇼',
'MXN': '🇲🇽', 'MYR': '🇲🇾', 'MZN': '🇲🇿', 'NAD': '🇳🇦', 'NGN': '🇳🇬',
'NIO': '🇳🇮', 'NOK': '🇳🇴', 'NPR': '🇳🇵', 'NZD': '🇳🇿', 'OMR': '🇴🇲',
'PAB': '🇵🇦', 'PEN': '🇵🇪', 'PGK': '🇵🇬', 'PHP': '🇵🇭', 'PKR': '🇵🇰',
'PLN': '🇵🇱', 'PYG': '🇵🇾', 'QAR': '🇶🇦', 'RON': '🇷🇴', 'RSD': '🇷🇸',
'RUB': '🇷🇺', 'RWF': '🇷🇼', 'SAR': '🇸🇦', 'SBD': '🇸🇧', 'SCR': '🇸🇨',
'SDG': '🇸🇩', 'SEK': '🇸🇪', 'SHP': '🇸🇭', 'SLE': '🇸🇱', 'SLL': '🇸🇱',
'SOS': '🇸🇴', 'SRD': '🇸🇷', 'SSP': '🇸🇸', 'STN': '🇸🇹', 'SYP': '🇸🇾',
'SZL': '🇸🇿', 'TJS': '🇹🇯', 'TMT': '🇹🇲', 'TND': '🇹🇳', 'TOP': '🇹🇴',
'TRY': '🇹🇷', 'TTD': '🇹🇹', 'TVD': '🇹🇻', 'TWD': '🇹🇼', 'TZS': '🇹🇿',
'UAH': '🇺🇦', 'UGX': '🇺🇬', 'UYU': '🇺🇾', 'UZS': '🇺🇿', 'VES': '🇻🇪',
'VND': '🇻🇳', 'VUV': '🇻🇺', 'WST': '🇼🇸', 'XAF': '🌍', 'XCD': '🏝️',
'XCG': '🏝️', 'XDR': '🌐', 'XOF': '🌍', 'XPF': '🌊', 'YER': '🇾🇪',
'ZAR': '🇿🇦', 'ZMW': '🇿🇲', 'ZWL': '🇿🇼'
};
// DOM元素
let elements = {};
let currentRates = [];
let filteredRates = [];
// 初始化
document.addEventListener('DOMContentLoaded', function() {
initElements();
initCurrencySelector();
bindEvents();
loadExchangeRates();
});
// 初始化DOM元素
function initElements() {
elements = {
currencySelect: document.getElementById('currency-select'),
searchInput: document.getElementById('search-input'),
loading: document.getElementById('loading'),
content: document.getElementById('exchange-content'),
baseCurrency: document.getElementById('base-currency'),
updateTime: document.getElementById('update-time'),
ratesGrid: document.getElementById('rates-grid'),
totalCurrencies: document.getElementById('total-currencies'),
lastUpdate: document.getElementById('last-update')
};
}
// 初始化货币选择器
function initCurrencySelector() {
if (!elements.currencySelect) return;
// 添加常用货币选项
POPULAR_CURRENCIES.forEach(currency => {
const option = document.createElement('option');
option.value = currency.code;
option.textContent = `${currency.flag} ${currency.code} - ${currency.name}`;
if (currency.code === API.defaultCurrency) {
option.selected = true;
}
elements.currencySelect.appendChild(option);
});
}
// 绑定事件
function bindEvents() {
// 货币选择变化
if (elements.currencySelect) {
elements.currencySelect.addEventListener('change', function() {
loadExchangeRates(this.value);
});
}
// 搜索功能
if (elements.searchInput) {
elements.searchInput.addEventListener('input', function() {
filterRates(this.value);
});
}
}
// 加载汇率数据
async function loadExchangeRates(currency = API.defaultCurrency) {
try {
showLoading(true);
// 尝试从API获取数据
const data = await fetchFromAPI(currency);
if (data && data.code === 200 && data.data) {
currentRates = data.data.rates || [];
displayExchangeRates(data.data);
} else {
// 尝试从本地获取数据
const localData = await fetchFromLocal();
if (localData && localData.code === 200 && localData.data) {
currentRates = localData.data.rates || [];
displayExchangeRates(localData.data);
showError('使用本地数据,可能不是最新汇率');
} else {
throw new Error('无法获取汇率数据');
}
}
} catch (error) {
console.error('加载汇率失败:', error);
showError('加载汇率数据失败,请稍后重试');
} finally {
showLoading(false);
}
}
// 从API获取数据
async function fetchFromAPI(currency) {
// 初始化API接口列表
await API.init();
// 重置API索引到第一个接口
API.reset();
// 尝试所有API接口
for (let i = 0; i < API.endpoints.length; i++) {
try {
const url = API.getCurrentUrl(currency);
console.log(`尝试接口 ${i + 1}/${API.endpoints.length}: ${url}`);
const response = await fetch(url, {
cache: 'no-store'
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const data = await response.json();
if (data && data.code === 200) {
console.log(`接口 ${i + 1} 请求成功`);
return data;
}
throw new Error(data && data.message ? data.message : '接口返回异常');
} catch (e) {
console.warn(`接口 ${i + 1} 失败:`, e.message);
// 如果不是最后一个接口,切换到下一个
if (i < API.endpoints.length - 1) {
API.switchToNext();
continue;
}
// 所有接口都失败了
console.warn('所有远程接口都失败,尝试本地数据');
return null;
}
}
}
// 从本地获取数据
async function fetchFromLocal() {
try {
const response = await fetch(API.localFallback + `?t=${Date.now()}`);
if (!response.ok) throw new Error(`本地文件HTTP ${response.status}`);
const data = await response.json();
return data;
} catch (e) {
console.error('读取本地返回接口.json失败:', e);
return null;
}
}
// 显示汇率数据
function displayExchangeRates(data) {
if (!data || !data.rates) {
showError('没有获取到汇率数据');
return;
}
// 更新基础货币信息
if (elements.baseCurrency) {
const baseCurrencyName = CURRENCY_NAMES[data.base_code] || data.base_code;
const baseCurrencyFlag = CURRENCY_FLAGS[data.base_code] || '💱';
elements.baseCurrency.textContent = `${baseCurrencyFlag} ${data.base_code} - ${baseCurrencyName}`;
}
// 更新时间信息
if (elements.updateTime && data.updated) {
elements.updateTime.textContent = `更新时间: ${data.updated}`;
}
// 更新统计信息
updateStats(data);
// 显示汇率列表
filteredRates = data.rates;
renderRates(filteredRates);
// 显示内容区域
if (elements.content) {
elements.content.classList.add('fade-in');
elements.content.style.display = 'block';
}
}
// 更新统计信息
function updateStats(data) {
if (elements.totalCurrencies) {
elements.totalCurrencies.textContent = data.rates ? data.rates.length : 0;
}
if (elements.lastUpdate && data.updated) {
elements.lastUpdate.textContent = data.updated;
}
}
// 渲染汇率列表
function renderRates(rates) {
if (!elements.ratesGrid || !rates) return;
// 按优先级排序货币
const sortedRates = [...rates].sort((a, b) => {
const priorityA = CURRENCY_PRIORITY[a.currency] || 999;
const priorityB = CURRENCY_PRIORITY[b.currency] || 999;
// 优先级相同时按货币代码字母顺序排序
if (priorityA === priorityB) {
return a.currency.localeCompare(b.currency);
}
return priorityA - priorityB;
});
elements.ratesGrid.innerHTML = '';
sortedRates.forEach(rate => {
const rateCard = createRateCard(rate);
elements.ratesGrid.appendChild(rateCard);
});
}
// 创建汇率卡片
function createRateCard(rate) {
const card = document.createElement('div');
card.className = 'rate-card';
const currencyName = CURRENCY_NAMES[rate.currency] || rate.currency;
const currencyFlag = CURRENCY_FLAGS[rate.currency] || '💱';
card.innerHTML = `
<div class="currency-code">
<span class="currency-flag">${currencyFlag}</span>
${rate.currency}
</div>
<div class="exchange-rate">${formatRate(rate.rate)}</div>
<div class="currency-name">${currencyName}</div>
`;
return card;
}
// 格式化汇率
function formatRate(rate) {
if (rate >= 1) {
return rate.toFixed(4);
} else if (rate >= 0.01) {
return rate.toFixed(6);
} else {
return rate.toFixed(8);
}
}
// 过滤汇率数据
function filterRates(searchTerm) {
if (!searchTerm.trim()) {
renderRates(currentRates);
return;
}
const filtered = currentRates.filter(rate => {
const currencyName = CURRENCY_NAMES[rate.currency] || rate.currency;
return rate.currency.toLowerCase().includes(searchTerm.toLowerCase()) ||
currencyName.toLowerCase().includes(searchTerm.toLowerCase());
});
renderRates(filtered);
}
// 显示/隐藏加载状态
function showLoading(show) {
if (elements.loading) {
elements.loading.style.display = show ? 'block' : 'none';
}
if (elements.content) {
elements.content.style.display = show ? 'none' : 'block';
}
}
// 显示错误信息
function showError(message) {
if (elements.content) {
elements.content.innerHTML = `
<div class="error">
<h3>⚠️ 加载失败</h3>
<p>${escapeHtml(message)}</p>
<p>请检查网络连接或稍后重试</p>
</div>
`;
elements.content.style.display = 'block';
}
}
// HTML转义
function escapeHtml(text) {
if (!text) return '';
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
// 错误处理
window.addEventListener('error', function(event) {
console.error('页面错误:', event.error);
});
// 网络状态监听
window.addEventListener('online', function() {
console.log('网络已连接');
});
window.addEventListener('offline', function() {
console.log('网络已断开');
showError('网络连接已断开,请检查网络设置');
});
// 导出函数供外部调用
window.ExchangeRate = {
loadExchangeRates,
showError,
showLoading
};

View File

@@ -1,7 +0,0 @@
[
"https://60s-cf.viki.moe",
"https://60s.viki.moe",
"https://60s.b23.run",
"https://60s.114128.xyz",
"https://60s-cf.114128.xyz"
]

File diff suppressed because one or more lines are too long

View File

@@ -1,106 +0,0 @@
/* 彩虹背景相关样式 */
body {
background: linear-gradient(
135deg,
#ff6b6b 0%,
#4ecdc4 12.5%,
#45b7d1 25%,
#96ceb4 37.5%,
#feca57 50%,
#ff9ff3 62.5%,
#54a0ff 75%,
#5f27cd 87.5%,
#00d2d3 100%
);
background-size: 400% 400%;
animation: rainbowGradient 15s ease infinite;
background-attachment: fixed;
min-height: 100vh;
position: relative;
}
@keyframes rainbowGradient {
0% {
background-position: 0% 50%;
}
25% {
background-position: 100% 50%;
}
50% {
background-position: 100% 100%;
}
75% {
background-position: 0% 100%;
}
100% {
background-position: 0% 50%;
}
}
/* 彩虹装饰层 */
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background:
radial-gradient(circle at 20% 20%, rgba(255, 107, 107, 0.15) 0%, transparent 50%),
radial-gradient(circle at 80% 80%, rgba(78, 205, 196, 0.15) 0%, transparent 50%),
radial-gradient(circle at 40% 80%, rgba(69, 183, 209, 0.12) 0%, transparent 40%),
radial-gradient(circle at 60% 20%, rgba(150, 206, 180, 0.12) 0%, transparent 40%),
radial-gradient(circle at 80% 40%, rgba(254, 202, 87, 0.1) 0%, transparent 35%);
pointer-events: none;
z-index: -1;
animation: float 20s ease-in-out infinite alternate;
}
/* 彩虹粒子效果 */
body::after {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image:
radial-gradient(circle at 10% 10%, rgba(255, 107, 107, 0.8) 2px, transparent 2px),
radial-gradient(circle at 30% 20%, rgba(78, 205, 196, 0.8) 1.5px, transparent 1.5px),
radial-gradient(circle at 50% 30%, rgba(69, 183, 209, 0.8) 1px, transparent 1px),
radial-gradient(circle at 70% 40%, rgba(150, 206, 180, 0.8) 2px, transparent 2px),
radial-gradient(circle at 90% 50%, rgba(254, 202, 87, 0.8) 1.5px, transparent 1.5px),
radial-gradient(circle at 20% 60%, rgba(255, 159, 243, 0.8) 1px, transparent 1px),
radial-gradient(circle at 40% 70%, rgba(84, 160, 255, 0.8) 2px, transparent 2px),
radial-gradient(circle at 60% 80%, rgba(95, 39, 205, 0.8) 1.5px, transparent 1.5px),
radial-gradient(circle at 80% 90%, rgba(0, 210, 211, 0.8) 1px, transparent 1px);
background-size: 200px 200px, 250px 250px, 180px 180px, 300px 300px, 220px 220px, 160px 160px, 280px 280px, 240px 240px, 200px 200px;
animation: sparkle 25s linear infinite;
pointer-events: none;
z-index: -1;
opacity: 0.6;
}
@keyframes float {
0% {
transform: translateY(0px) rotate(0deg);
}
100% {
transform: translateY(-15px) rotate(2deg);
}
}
@keyframes sparkle {
0%, 100% {
transform: translateX(0) translateY(0) scale(1);
}
25% {
transform: translateX(-10px) translateY(-5px) scale(1.1);
}
50% {
transform: translateX(10px) translateY(-10px) scale(0.9);
}
75% {
transform: translateX(-5px) translateY(-15px) scale(1.05);
}
}

View File

@@ -1,77 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>🔥 HackerNews 热门榜单</title>
<link rel="stylesheet" href="css/background.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="container">
<header class="header">
<div class="header-icon">🌈</div>
<h1 class="title">🔥 HackerNews 热门榜单 💻</h1>
<p class="subtitle">全球技术社区 · 实时热门话题</p>
<div class="tab-container">
<button class="tab-btn active" data-type="top">
<span class="tab-icon">🏆</span>
热门榜
</button>
<button class="tab-btn" data-type="new">
<span class="tab-icon">🆕</span>
最新榜
</button>
<button class="tab-btn" data-type="best">
<span class="tab-icon"></span>
最佳榜
</button>
</div>
<div class="update-time">
<span class="time-icon"></span>
<span id="updateTime">加载中...</span>
</div>
<button id="refreshBtn" class="refresh-btn">
<span class="btn-icon">🔄</span>
刷新数据
</button>
</header>
<div class="loading" id="loading">
<div class="loading-content">
<div class="rainbow-spinner"></div>
<div class="loading-text">
<span class="loading-emoji">🚀</span>
<p>正在获取最新榜单...</p>
<div class="loading-dots">
<span></span>
<span></span>
<span></span>
</div>
</div>
</div>
</div>
<div class="news-list" id="newsList">
<!-- 新闻列表将动态生成 -->
</div>
<div class="error-message" id="errorMessage" style="display: none;">
<div class="error-content">
<div class="error-icon">💥</div>
<h3>加载失败了</h3>
<p>网络连接出现问题,请稍后重试</p>
<button onclick="loadNewsList()" class="retry-btn">
<span>🔄</span>
重新加载
</button>
</div>
</div>
</div>
<script src="js/script.js"></script>
</body>
</html>

View File

@@ -1,338 +0,0 @@
// API接口列表
const API_ENDPOINTS = [
"https://60s-cf.viki.moe",
"https://60s.viki.moe",
"https://60s.b23.run",
"https://60s.114128.xyz",
"https://60s-cf.114128.xyz"
];
// 当前使用的API索引
let currentApiIndex = 0;
let currentType = 'top';
// DOM元素
const loadingElement = document.getElementById('loading');
const newsListElement = document.getElementById('newsList');
const errorMessageElement = document.getElementById('errorMessage');
const updateTimeElement = document.getElementById('updateTime');
const refreshBtn = document.getElementById('refreshBtn');
const tabBtns = document.querySelectorAll('.tab-btn');
// 页面加载完成后自动加载数据
document.addEventListener('DOMContentLoaded', function() {
loadNewsList();
initTabEvents();
});
// 初始化标签事件
function initTabEvents() {
tabBtns.forEach(btn => {
btn.addEventListener('click', function() {
const type = this.getAttribute('data-type');
if (type !== currentType) {
currentType = type;
updateActiveTab(this);
loadNewsList();
}
});
});
}
// 更新活跃标签
function updateActiveTab(activeBtn) {
tabBtns.forEach(btn => btn.classList.remove('active'));
activeBtn.classList.add('active');
}
// 刷新按钮点击事件
refreshBtn.addEventListener('click', function() {
loadNewsList();
});
// 加载新闻列表
async function loadNewsList() {
showLoading();
hideError();
try {
const data = await fetchData();
displayNewsList(data.data);
updateRefreshTime();
} catch (error) {
console.error('加载失败:', error);
showError();
}
hideLoading();
}
// 获取数据
async function fetchData() {
for (let i = 0; i < API_ENDPOINTS.length; i++) {
const apiUrl = API_ENDPOINTS[currentApiIndex];
try {
const response = await fetch(`${apiUrl}/v2/hacker-news/${currentType}`, {
method: 'GET',
headers: {
'Accept': 'application/json',
},
timeout: 10000
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
const data = await response.json();
if (data.code === 200 && data.data) {
return data;
} else {
throw new Error('数据格式错误');
}
} catch (error) {
console.error(`API ${apiUrl} 请求失败:`, error);
currentApiIndex = (currentApiIndex + 1) % API_ENDPOINTS.length;
if (i === API_ENDPOINTS.length - 1) {
throw new Error('所有API接口都无法访问');
}
}
}
}
// 显示新闻列表
function displayNewsList(newsData) {
newsListElement.innerHTML = '';
newsData.forEach((item, index) => {
const newsItem = createNewsItem(item, index + 1);
newsListElement.appendChild(newsItem);
});
}
// 创建新闻项目
function createNewsItem(item, rank) {
const newsItem = document.createElement('div');
newsItem.className = 'news-item';
const rankClass = rank <= 5 ? 'news-rank top-5' : 'news-rank';
const formattedScore = formatScore(item.score);
const formattedTime = formatTime(item.created);
// 根据排名添加特殊标识
let rankEmoji = '';
if (rank === 1) rankEmoji = '🏆';
else if (rank === 2) rankEmoji = '🥈';
else if (rank === 3) rankEmoji = '🥉';
else if (rank <= 10) rankEmoji = '💎';
else rankEmoji = '⭐';
// 根据评分添加热度指示
let heatLevel = '';
if (item.score >= 1000) heatLevel = '🔥🔥🔥';
else if (item.score >= 500) heatLevel = '🔥🔥';
else if (item.score >= 100) heatLevel = '🔥';
else heatLevel = '💫';
newsItem.innerHTML = `
<div class="news-header">
<div class="${rankClass}">${rank}</div>
<div class="news-score">${heatLevel} ${formattedScore}</div>
</div>
<div class="news-title">${rankEmoji} ${escapeHtml(item.title)}</div>
<div class="news-meta">
<div class="news-author">👤 ${escapeHtml(item.author)}</div>
<div class="news-time">🕒 ${formattedTime}</div>
</div>
<a href="${item.link}" target="_blank" class="news-link">
🚀 阅读全文
</a>
`;
return newsItem;
}
// 格式化评分
function formatScore(score) {
if (score >= 1000) {
return (score / 1000).toFixed(1) + 'K';
} else {
return score.toString();
}
}
// 格式化时间
function formatTime(timeStr) {
try {
const date = new Date(timeStr);
const now = new Date();
const diff = now - date;
const minutes = Math.floor(diff / (1000 * 60));
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);
if (days > 0) {
return `${days}天前`;
} else if (hours > 0) {
return `${hours}小时前`;
} else if (minutes > 0) {
return `${minutes}分钟前`;
} else {
return '刚刚';
}
} catch (error) {
return timeStr;
}
}
// HTML转义
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
// 更新刷新时间
function updateRefreshTime() {
const now = new Date();
const timeStr = now.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
});
updateTimeElement.textContent = `最后更新: ${timeStr}`;
// 添加成功提示
showSuccessMessage('🌈 数据已更新');
}
// 显示成功消息
function showSuccessMessage(message) {
// 移除之前的提示
const existingToast = document.querySelector('.success-toast');
if (existingToast) {
existingToast.remove();
}
const toast = document.createElement('div');
toast.className = 'success-toast';
toast.textContent = message;
toast.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
background: linear-gradient(135deg, #ff6b6b, #4ecdc4, #45b7d1);
color: white;
padding: 12px 20px;
border-radius: 25px;
box-shadow: 0 4px 20px rgba(255, 107, 107, 0.3);
z-index: 1000;
font-weight: 600;
font-size: 0.9em;
animation: rainbowToastSlide 0.5s ease-out;
backdrop-filter: blur(10px);
`;
document.body.appendChild(toast);
// 3秒后自动移除
setTimeout(() => {
toast.style.animation = 'rainbowToastSlideOut 0.5s ease-in forwards';
setTimeout(() => toast.remove(), 500);
}, 3000);
}
// 显示加载状态
function showLoading() {
loadingElement.style.display = 'block';
newsListElement.style.display = 'none';
}
// 隐藏加载状态
function hideLoading() {
loadingElement.style.display = 'none';
newsListElement.style.display = 'block';
}
// 显示错误信息
function showError() {
errorMessageElement.style.display = 'block';
newsListElement.style.display = 'none';
}
// 隐藏错误信息
function hideError() {
errorMessageElement.style.display = 'none';
}
// 添加CSS动画到页面
if (!document.querySelector('#toast-styles')) {
const style = document.createElement('style');
style.id = 'toast-styles';
style.textContent = `
@keyframes rainbowToastSlide {
from {
opacity: 0;
transform: translateX(100px) scale(0.8);
}
to {
opacity: 1;
transform: translateX(0) scale(1);
}
}
@keyframes rainbowToastSlideOut {
from {
opacity: 1;
transform: translateX(0) scale(1);
}
to {
opacity: 0;
transform: translateX(100px) scale(0.8);
}
}
.success-toast {
background-size: 200% 200%;
animation: rainbowToastSlide 0.5s ease-out, toastRainbow 2s ease-in-out infinite !important;
}
@keyframes toastRainbow {
0%, 100% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
}
`;
document.head.appendChild(style);
}
// 自动刷新 (每5分钟)
setInterval(function() {
loadNewsList();
}, 5 * 60 * 1000);
// 键盘快捷键支持
document.addEventListener('keydown', function(e) {
if (e.key === 'r' && (e.ctrlKey || e.metaKey)) {
e.preventDefault();
loadNewsList();
}
// 数字键切换标签
if (e.key >= '1' && e.key <= '3') {
e.preventDefault();
const typeMap = { '1': 'top', '2': 'new', '3': 'best' };
const targetType = typeMap[e.key];
const targetBtn = document.querySelector(`[data-type="${targetType}"]`);
if (targetBtn && targetType !== currentType) {
currentType = targetType;
updateActiveTab(targetBtn);
loadNewsList();
}
}
});

View File

@@ -1,7 +0,0 @@
[
"https://60s-cf.viki.moe",
"https://60s.viki.moe",
"https://60s.b23.run",
"https://60s.114128.xyz",
"https://60s-cf.114128.xyz"
]

View File

@@ -1,87 +0,0 @@
{
"code": 200,
"message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s反馈群 595941841",
"data": [
{
"id": 45087396,
"title": "We should have the ability to run any code we want on hardware we own",
"link": "https://hugotunius.se/2025/08/31/what-every-argument-about-sideloading-gets-wrong.html",
"score": 995,
"author": "K0nserv",
"created": "2025-08-31 21:46:26",
"created_at": 1756676786000
},
{
"id": 45053029,
"title": "Why countries trade with each other while fighting",
"link": "https://news.mit.edu/2025/why-countries-trade-each-other-while-fighting-mariya-grinberg-book-0828",
"score": 32,
"author": "LorenDB",
"created": "2025-08-28 14:58:28",
"created_at": 1756393108000
},
{
"id": 45086020,
"title": "Eternal Struggle",
"link": "https://yoavg.github.io/eternal/",
"score": 481,
"author": "yurivish",
"created": "2025-08-31 19:04:03",
"created_at": 1756667043000
},
{
"id": 45052960,
"title": "C++: Strongly Happens Before?",
"link": "https://nekrozqliphort.github.io/posts/happens-b4/",
"score": 16,
"author": "signa11",
"created": "2025-08-28 14:54:37",
"created_at": 1756392877000
},
{
"id": 45087971,
"title": "Nintendo Switch 2 Dock USB-C Compatibility",
"link": "https://www.lttlabs.com/blog/2025/08/30/nintendo-switch-2-dock",
"score": 192,
"author": "croes",
"created": "2025-08-31 23:21:46",
"created_at": 1756682506000
},
{
"id": 45082731,
"title": "“This telegram must be closely paraphrased before being communicated to anyone”",
"link": "https://history.stackexchange.com/questions/79371/this-telegram-must-be-closely-paraphrased-before-being-communicated-to-anyone",
"score": 645,
"author": "azeemba",
"created": "2025-08-31 12:39:47",
"created_at": 1756643987000
},
{
"id": 45089256,
"title": "What Is Complexity in Chess?",
"link": "https://lichess.org/@/Toadofsky/blog/what-is-complexity/pKo1swFh",
"score": 41,
"author": "fzliu",
"created": "2025-09-01 03:45:33",
"created_at": 1756698333000
},
{
"id": 45087815,
"title": "Lewis and Clark marked their trail with laxatives",
"link": "https://offbeatoregon.com/2501d1006d_biliousPills-686.077.html",
"score": 141,
"author": "toomuchtodo",
"created": "2025-08-31 22:54:26",
"created_at": 1756680866000
},
{
"id": 45083952,
"title": "Jujutsu for everyone",
"link": "https://jj-for-everyone.github.io/",
"score": 363,
"author": "Bogdanp",
"created": "2025-08-31 15:31:04",
"created_at": 1756654264000
}
]
}

View File

@@ -1,40 +0,0 @@
.background-container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
overflow: hidden;
}
.rainbow-gradient {
position: absolute;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
background: linear-gradient(
217deg,
rgba(255, 0, 0, 0.6),
rgba(255, 0, 0, 0) 70.71%
), linear-gradient(
127deg,
rgba(0, 255, 0, 0.6),
rgba(0, 255, 0, 0) 70.71%
), linear-gradient(
336deg,
rgba(0, 0, 255, 0.6),
rgba(0, 0, 255, 0) 70.71%
);
animation: rainbow-rotate 15s linear infinite;
}
@keyframes rainbow-rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}

View File

@@ -1,155 +0,0 @@
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif;
color: #333;
background-color: #f5f5f5;
position: relative;
min-height: 100vh;
}
.container {
max-width: 800px;
margin: 0 auto;
padding: 20px;
position: relative;
z-index: 1;
background-color: rgba(255, 255, 255, 0.85);
border-radius: 10px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
header {
text-align: center;
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 1px solid #eaeaea;
}
header h1 {
color: #07a35a;
margin-bottom: 10px;
font-size: 2rem;
}
.update-time {
color: #888;
font-size: 0.9rem;
}
.hot-list {
list-style: none;
}
.hot-item {
padding: 15px;
margin-bottom: 10px;
border-radius: 8px;
background-color: white;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
transition: transform 0.2s, box-shadow 0.2s;
display: flex;
align-items: center;
}
.hot-item:hover {
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
.hot-rank {
font-size: 1.2rem;
font-weight: bold;
color: #ff8200;
margin-right: 15px;
min-width: 30px;
text-align: center;
}
.hot-rank.top-1 {
color: #ff4500;
}
.hot-rank.top-2, .hot-rank.top-3 {
color: #ff6600;
}
.hot-content {
flex: 1;
}
.hot-title {
font-size: 1.1rem;
margin-bottom: 5px;
color: #333;
text-decoration: none;
display: block;
}
.hot-title:hover {
color: #07a35a;
}
.hot-value {
font-size: 0.85rem;
color: #888;
}
.loading {
text-align: center;
padding: 20px;
color: #888;
}
footer {
text-align: center;
margin-top: 30px;
padding-top: 15px;
border-top: 1px solid #eaeaea;
color: #888;
font-size: 0.9rem;
}
/* 响应式设计 */
/* 手机端 */
@media (max-width: 576px) {
.container {
padding: 15px;
margin: 10px;
}
header h1 {
font-size: 1.5rem;
}
.hot-item {
padding: 12px;
}
.hot-rank {
font-size: 1rem;
min-width: 25px;
margin-right: 10px;
}
.hot-title {
font-size: 1rem;
}
}
/* 平板端 */
@media (min-width: 577px) and (max-width: 992px) {
.container {
max-width: 90%;
}
header h1 {
font-size: 1.8rem;
}
}
/* 电脑端 - 默认样式已经设置 */

View File

@@ -1,34 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>微博热搜榜</title>
<link rel="stylesheet" href="./css/style.css">
<link rel="stylesheet" href="./css/background.css">
</head>
<body>
<div class="background-container">
<div class="rainbow-gradient"></div>
</div>
<div class="container">
<header>
<h1>微博热搜榜</h1>
<div class="update-time" id="updateTime"></div>
</header>
<main>
<div class="hot-list" id="hotList">
<div class="loading">加载中...</div>
</div>
</main>
<footer>
<p>数据来源于微博热搜榜</p>
</footer>
</div>
<script src="./js/main.js"></script>
</body>
</html>

View File

@@ -1,94 +0,0 @@
// API接口列表
const API_ENDPOINTS = [
"https://60s-cf.viki.moe/v2/weibo",
"https://60s.viki.moe/v2/weibo",
"https://60s.b23.run/v2/weibo",
"https://60s.114128.xyz/v2/weibo",
"https://60s-cf.114128.xyz/v2/weibo"
];
// 当前使用的API索引
let currentApiIndex = 0;
// DOM元素
const hotListElement = document.getElementById('hotList');
const updateTimeElement = document.getElementById('updateTime');
// 格式化时间
function formatDate(date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
// 渲染热搜列表
function renderHotList(data) {
hotListElement.innerHTML = '';
data.forEach((item, index) => {
const hotItem = document.createElement('div');
hotItem.className = 'hot-item';
const rankClass = index < 3 ? `top-${index + 1}` : '';
hotItem.innerHTML = `
<div class="hot-rank ${rankClass}">${index + 1}</div>
<div class="hot-content">
<a href="${item.link}" class="hot-title" target="_blank">${item.title}</a>
${item.hot_value ? `<div class="hot-value">${item.hot_value}</div>` : ''}
</div>
`;
hotListElement.appendChild(hotItem);
});
// 更新时间
updateTimeElement.textContent = `更新时间:${formatDate(new Date())}`;
}
// 获取微博热搜数据
async function fetchWeiboHotList() {
try {
const response = await fetch(API_ENDPOINTS[currentApiIndex]);
if (!response.ok) {
throw new Error('网络响应不正常');
}
const result = await response.json();
if (result.code === 200 && result.data) {
renderHotList(result.data);
} else {
throw new Error('数据格式错误');
}
} catch (error) {
console.error('获取数据失败:', error);
// 尝试切换到下一个API
currentApiIndex = (currentApiIndex + 1) % API_ENDPOINTS.length;
// 显示错误信息
hotListElement.innerHTML = `
<div class="loading">
获取数据失败,正在尝试其他接口...
</div>
`;
// 延迟后重试
setTimeout(fetchWeiboHotList, 2000);
}
}
// 页面加载完成后获取数据
document.addEventListener('DOMContentLoaded', () => {
fetchWeiboHotList();
// 每隔5分钟刷新一次数据
setInterval(fetchWeiboHotList, 5 * 60 * 1000);
});

View File

@@ -1,7 +0,0 @@
[
"https://60s-cf.viki.moe",
"https://60s.viki.moe",
"https://60s.b23.run",
"https://60s.114128.xyz",
"https://60s-cf.114128.xyz"
]

View File

@@ -1,261 +0,0 @@
{
"code": 200,
"message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s反馈群 595941841",
"data": [
{
"title": "00后男生0.6秒飞针采血惊呆患者",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=00%E5%90%8E%E7%94%B7%E7%94%9F0.6%E7%A7%92%E9%A3%9E%E9%92%88%E9%87%87%E8%A1%80%E6%83%8A%E5%91%86%E6%82%A3%E8%80%85"
},
{
"title": "普京带3位副总理10多位部长到中国",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E6%99%AE%E4%BA%AC%E5%B8%A63%E4%BD%8D%E5%89%AF%E6%80%BB%E7%90%8610%E5%A4%9A%E4%BD%8D%E9%83%A8%E9%95%BF%E5%88%B0%E4%B8%AD%E5%9B%BD"
},
{
"title": "始终高举上海精神旗帜",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E5%A7%8B%E7%BB%88%E9%AB%98%E4%B8%BE%E4%B8%8A%E6%B5%B7%E7%B2%BE%E7%A5%9E%E6%97%97%E5%B8%9C"
},
{
"title": "女生苦练化妆1年的变化",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E5%A5%B3%E7%94%9F%E8%8B%A6%E7%BB%83%E5%8C%96%E5%A6%861%E5%B9%B4%E7%9A%84%E5%8F%98%E5%8C%96"
},
{
"title": "香港1200架无人机重现日本投降矣",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E9%A6%99%E6%B8%AF1200%E6%9E%B6%E6%97%A0%E4%BA%BA%E6%9C%BA%E9%87%8D%E7%8E%B0%E6%97%A5%E6%9C%AC%E6%8A%95%E9%99%8D%E7%9F%A3"
},
{
"title": "尚公主全阵容官宣",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E5%B0%9A%E5%85%AC%E4%B8%BB%E5%85%A8%E9%98%B5%E5%AE%B9%E5%AE%98%E5%AE%A3"
},
{
"title": "真的可以永远相信刘宇舞台",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E7%9C%9F%E7%9A%84%E5%8F%AF%E4%BB%A5%E6%B0%B8%E8%BF%9C%E7%9B%B8%E4%BF%A1%E5%88%98%E5%AE%87%E8%88%9E%E5%8F%B0"
},
{
"title": "九三阅兵徒步方队铿锵步伐",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E4%B9%9D%E4%B8%89%E9%98%85%E5%85%B5%E5%BE%92%E6%AD%A5%E6%96%B9%E9%98%9F%E9%93%BF%E9%94%B5%E6%AD%A5%E4%BC%90"
},
{
"title": "唐朝诡事录",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E5%94%90%E6%9C%9D%E8%AF%A1%E4%BA%8B%E5%BD%95"
},
{
"title": "抗战胜利80周年第3场记者招待会",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E6%8A%97%E6%88%98%E8%83%9C%E5%88%A980%E5%91%A8%E5%B9%B4%E7%AC%AC3%E5%9C%BA%E8%AE%B0%E8%80%85%E6%8B%9B%E5%BE%85%E4%BC%9A"
},
{
"title": "王曼昱钱天一3比2蒯曼孙颖莎",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E7%8E%8B%E6%9B%BC%E6%98%B1%E9%92%B1%E5%A4%A9%E4%B8%803%E6%AF%942%E8%92%AF%E6%9B%BC%E5%AD%99%E9%A2%96%E8%8E%8E"
},
{
"title": "张维伊对96岁的姥姥说长命百岁",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E5%BC%A0%E7%BB%B4%E4%BC%8A%E5%AF%B996%E5%B2%81%E7%9A%84%E5%A7%A5%E5%A7%A5%E8%AF%B4%E9%95%BF%E5%91%BD%E7%99%BE%E5%B2%81"
},
{
"title": "孟子义李昀锐定妆照",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E5%AD%9F%E5%AD%90%E4%B9%89%E6%9D%8E%E6%98%80%E9%94%90%E5%AE%9A%E5%A6%86%E7%85%A7"
},
{
"title": "以为张艺兴穿的蓝色抹胸",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E4%BB%A5%E4%B8%BA%E5%BC%A0%E8%89%BA%E5%85%B4%E7%A9%BF%E7%9A%84%E8%93%9D%E8%89%B2%E6%8A%B9%E8%83%B8"
},
{
"title": "尚公主开机",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E5%B0%9A%E5%85%AC%E4%B8%BB%E5%BC%80%E6%9C%BA"
},
{
"title": "心动的信号8",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E5%BF%83%E5%8A%A8%E7%9A%84%E4%BF%A1%E5%8F%B78"
},
{
"title": "霍建华病娇疯批演爽了",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E9%9C%8D%E5%BB%BA%E5%8D%8E%E7%97%85%E5%A8%87%E7%96%AF%E6%89%B9%E6%BC%94%E7%88%BD%E4%BA%86"
},
{
"title": "普京抵达天津",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E6%99%AE%E4%BA%AC%E6%8A%B5%E8%BE%BE%E5%A4%A9%E6%B4%A5"
},
{
"title": "龚俊的体面只给旅游前几天",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E9%BE%9A%E4%BF%8A%E7%9A%84%E4%BD%93%E9%9D%A2%E5%8F%AA%E7%BB%99%E6%97%85%E6%B8%B8%E5%89%8D%E5%87%A0%E5%A4%A9"
},
{
"title": "开学焦虑更严重的另有其人",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E5%BC%80%E5%AD%A6%E7%84%A6%E8%99%91%E6%9B%B4%E4%B8%A5%E9%87%8D%E7%9A%84%E5%8F%A6%E6%9C%89%E5%85%B6%E4%BA%BA"
},
{
"title": "那英小发雷霆",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E9%82%A3%E8%8B%B1%E5%B0%8F%E5%8F%91%E9%9B%B7%E9%9C%86"
},
{
"title": "居然有演员一句台词背1小时",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E5%B1%85%E7%84%B6%E6%9C%89%E6%BC%94%E5%91%98%E4%B8%80%E5%8F%A5%E5%8F%B0%E8%AF%8D%E8%83%8C1%E5%B0%8F%E6%97%B6"
},
{
"title": "谁教魏哲鸣冷脸跳这些的",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E8%B0%81%E6%95%99%E9%AD%8F%E5%93%B2%E9%B8%A3%E5%86%B7%E8%84%B8%E8%B7%B3%E8%BF%99%E4%BA%9B%E7%9A%84"
},
{
"title": "朱孝天爆冷出局",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E6%9C%B1%E5%AD%9D%E5%A4%A9%E7%88%86%E5%86%B7%E5%87%BA%E5%B1%80"
},
{
"title": "俄军称掌握战略主动权",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E4%BF%84%E5%86%9B%E7%A7%B0%E6%8E%8C%E6%8F%A1%E6%88%98%E7%95%A5%E4%B8%BB%E5%8A%A8%E6%9D%83"
},
{
"title": "谈恋爱3个月定律",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E8%B0%88%E6%81%8B%E7%88%B13%E4%B8%AA%E6%9C%88%E5%AE%9A%E5%BE%8B"
},
{
"title": "沈腾说错了最怕人笨还不勤快",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E6%B2%88%E8%85%BE%E8%AF%B4%E9%94%99%E4%BA%86%E6%9C%80%E6%80%95%E4%BA%BA%E7%AC%A8%E8%BF%98%E4%B8%8D%E5%8B%A4%E5%BF%AB"
},
{
"title": "王菲最新状态",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E7%8E%8B%E8%8F%B2%E6%9C%80%E6%96%B0%E7%8A%B6%E6%80%81"
},
{
"title": "张紫宁转行当拉拉队经理人了",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E5%BC%A0%E7%B4%AB%E5%AE%81%E8%BD%AC%E8%A1%8C%E5%BD%93%E6%8B%89%E6%8B%89%E9%98%9F%E7%BB%8F%E7%90%86%E4%BA%BA%E4%BA%86"
},
{
"title": "金价大涨两大原因",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E9%87%91%E4%BB%B7%E5%A4%A7%E6%B6%A8%E4%B8%A4%E5%A4%A7%E5%8E%9F%E5%9B%A0"
},
{
"title": "陕西Shaanxi官方标准拼音",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E9%99%95%E8%A5%BFShaanxi%E5%AE%98%E6%96%B9%E6%A0%87%E5%87%86%E6%8B%BC%E9%9F%B3"
},
{
"title": "边伯贤跳刀马刀马",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E8%BE%B9%E4%BC%AF%E8%B4%A4%E8%B7%B3%E5%88%80%E9%A9%AC%E5%88%80%E9%A9%AC"
},
{
"title": "冷冻太久的肉就不要再吃了",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E5%86%B7%E5%86%BB%E5%A4%AA%E4%B9%85%E7%9A%84%E8%82%89%E5%B0%B1%E4%B8%8D%E8%A6%81%E5%86%8D%E5%90%83%E4%BA%86"
},
{
"title": "95后00后恋爱有代沟",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=95%E5%90%8E00%E5%90%8E%E6%81%8B%E7%88%B1%E6%9C%89%E4%BB%A3%E6%B2%9F"
},
{
"title": "易烊千玺抢票",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E6%98%93%E7%83%8A%E5%8D%83%E7%8E%BA%E6%8A%A2%E7%A5%A8"
},
{
"title": "孙闻被乒协处罚",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E5%AD%99%E9%97%BB%E8%A2%AB%E4%B9%92%E5%8D%8F%E5%A4%84%E7%BD%9A"
},
{
"title": "这居然是白举纲",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E8%BF%99%E5%B1%85%E7%84%B6%E6%98%AF%E7%99%BD%E4%B8%BE%E7%BA%B2"
},
{
"title": "纪凌尘出演孟子义新剧",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E7%BA%AA%E5%87%8C%E5%B0%98%E5%87%BA%E6%BC%94%E5%AD%9F%E5%AD%90%E4%B9%89%E6%96%B0%E5%89%A7"
},
{
"title": "外卖员妈妈暴雨中将孩子托付派出所",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E5%A4%96%E5%8D%96%E5%91%98%E5%A6%88%E5%A6%88%E6%9A%B4%E9%9B%A8%E4%B8%AD%E5%B0%86%E5%AD%A9%E5%AD%90%E6%89%98%E4%BB%98%E6%B4%BE%E5%87%BA%E6%89%80"
},
{
"title": "我点外卖没用上券就这样",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E6%88%91%E7%82%B9%E5%A4%96%E5%8D%96%E6%B2%A1%E7%94%A8%E4%B8%8A%E5%88%B8%E5%B0%B1%E8%BF%99%E6%A0%B7"
},
{
"title": "孙颖莎小时候真来过新疆",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E5%AD%99%E9%A2%96%E8%8E%8E%E5%B0%8F%E6%97%B6%E5%80%99%E7%9C%9F%E6%9D%A5%E8%BF%87%E6%96%B0%E7%96%86"
},
{
"title": "印尼首都交通瘫痪",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E5%8D%B0%E5%B0%BC%E9%A6%96%E9%83%BD%E4%BA%A4%E9%80%9A%E7%98%AB%E7%97%AA"
},
{
"title": "停狗位停满了小狗",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E5%81%9C%E7%8B%97%E4%BD%8D%E5%81%9C%E6%BB%A1%E4%BA%86%E5%B0%8F%E7%8B%97"
},
{
"title": "怪不得校服裤子屁股锃亮",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E6%80%AA%E4%B8%8D%E5%BE%97%E6%A0%A1%E6%9C%8D%E8%A3%A4%E5%AD%90%E5%B1%81%E8%82%A1%E9%94%83%E4%BA%AE"
},
{
"title": "这一幕幕中国浪漫看得心暖暖",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E8%BF%99%E4%B8%80%E5%B9%95%E5%B9%95%E4%B8%AD%E5%9B%BD%E6%B5%AA%E6%BC%AB%E7%9C%8B%E5%BE%97%E5%BF%83%E6%9A%96%E6%9A%96"
},
{
"title": "林书豪退役",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E6%9E%97%E4%B9%A6%E8%B1%AA%E9%80%80%E5%BD%B9"
},
{
"title": "小猫咪舔毛把自己累睡着",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E5%B0%8F%E7%8C%AB%E5%92%AA%E8%88%94%E6%AF%9B%E6%8A%8A%E8%87%AA%E5%B7%B1%E7%B4%AF%E7%9D%A1%E7%9D%80"
},
{
"title": "iPhone17国行预计涨价500元",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=iPhone17%E5%9B%BD%E8%A1%8C%E9%A2%84%E8%AE%A1%E6%B6%A8%E4%BB%B7500%E5%85%83"
},
{
"title": "土耳其总统埃尔多安抵达天津",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E5%9C%9F%E8%80%B3%E5%85%B6%E6%80%BB%E7%BB%9F%E5%9F%83%E5%B0%94%E5%A4%9A%E5%AE%89%E6%8A%B5%E8%BE%BE%E5%A4%A9%E6%B4%A5"
},
{
"title": "脱口秀和Ta的朋友们",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E8%84%B1%E5%8F%A3%E7%A7%80%E5%92%8CTa%E7%9A%84%E6%9C%8B%E5%8F%8B%E4%BB%AC"
},
{
"title": "孟子义暮晚摇",
"hot_value": 0,
"link": "https://s.weibo.com/weibo?q=%E5%AD%9F%E5%AD%90%E4%B9%89%E6%9A%AE%E6%99%9A%E6%91%87"
}
]
}

View File

@@ -1,52 +0,0 @@
/* 背景相关样式 */
body {
background: linear-gradient(135deg, #e8f5e8 0%, #c8e6c9 25%, #a5d6a7 50%, #81c784 75%, #66bb6a 100%);
background-attachment: fixed;
min-height: 100vh;
position: relative;
}
/* 背景装饰元素 */
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image:
radial-gradient(circle at 20% 80%, rgba(120, 200, 120, 0.15) 0%, transparent 50%),
radial-gradient(circle at 80% 20%, rgba(100, 180, 100, 0.15) 0%, transparent 50%),
radial-gradient(circle at 40% 40%, rgba(140, 220, 140, 0.1) 0%, transparent 50%),
radial-gradient(circle at 60% 70%, rgba(160, 240, 160, 0.08) 0%, transparent 40%);
pointer-events: none;
z-index: -1;
}
/* 浮动装饰圆点 */
body::after {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image:
radial-gradient(circle at 10% 10%, rgba(76, 175, 80, 0.1) 2px, transparent 2px),
radial-gradient(circle at 90% 90%, rgba(76, 175, 80, 0.08) 1px, transparent 1px),
radial-gradient(circle at 30% 80%, rgba(76, 175, 80, 0.06) 1.5px, transparent 1.5px),
radial-gradient(circle at 70% 20%, rgba(76, 175, 80, 0.05) 1px, transparent 1px);
background-size: 100px 100px, 150px 150px, 80px 80px, 120px 120px;
animation: float 20s ease-in-out infinite alternate;
pointer-events: none;
z-index: -1;
}
@keyframes float {
0% {
transform: translateY(0px) rotate(0deg);
}
100% {
transform: translateY(-10px) rotate(1deg);
}
}

View File

@@ -1,956 +0,0 @@
/* 重置样式 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif;
line-height: 1.6;
color: #2e7d32;
overflow-x: hidden;
}
/* 容器 */
.container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
animation: containerFadeIn 0.8s ease-out;
}
@keyframes containerFadeIn {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* 头部 */
.header {
text-align: center;
margin-bottom: 40px;
background: rgba(255, 255, 255, 0.95);
padding: 35px 25px;
border-radius: 20px;
box-shadow: 0 8px 32px rgba(46, 125, 50, 0.12);
backdrop-filter: blur(15px);
border: 1px solid rgba(255, 255, 255, 0.3);
position: relative;
overflow: hidden;
}
.header::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(76, 175, 80, 0.1), transparent);
animation: shimmer 3s infinite;
}
@keyframes shimmer {
0% { left: -100%; }
100% { left: 100%; }
}
.header-icon {
font-size: 3em;
margin-bottom: 10px;
animation: bounce 2s infinite;
}
@keyframes bounce {
0%, 20%, 50%, 80%, 100% { transform: translateY(0); }
40% { transform: translateY(-10px); }
60% { transform: translateY(-5px); }
}
.title {
font-size: 2.8em;
font-weight: 700;
color: #1b5e20;
margin-bottom: 8px;
text-shadow: 0 2px 4px rgba(46, 125, 50, 0.1);
letter-spacing: 1px;
}
.subtitle {
font-size: 1.1em;
color: #4caf50;
margin-bottom: 20px;
font-weight: 500;
opacity: 0.9;
}
.update-time {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
color: #4caf50;
font-size: 0.95em;
margin-bottom: 20px;
padding: 8px 16px;
background: rgba(76, 175, 80, 0.1);
border-radius: 20px;
display: inline-flex;
}
.time-icon {
font-size: 1.1em;
animation: tick 1s infinite;
}
@keyframes tick {
0%, 50% { transform: rotate(0deg); }
25% { transform: rotate(15deg); }
75% { transform: rotate(-15deg); }
}
.refresh-btn {
background: linear-gradient(135deg, #4caf50, #66bb6a, #81c784);
color: white;
border: none;
padding: 12px 30px;
border-radius: 30px;
cursor: pointer;
font-size: 1em;
font-weight: 600;
transition: all 0.3s ease;
box-shadow: 0 4px 15px rgba(76, 175, 80, 0.3);
display: inline-flex;
align-items: center;
gap: 8px;
position: relative;
overflow: hidden;
}
.refresh-btn::before {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 0;
height: 0;
background: rgba(255, 255, 255, 0.2);
border-radius: 50%;
transform: translate(-50%, -50%);
transition: all 0.5s ease;
}
.refresh-btn:hover::before {
width: 300px;
height: 300px;
}
.refresh-btn:hover {
background: linear-gradient(135deg, #388e3c, #4caf50, #66bb6a);
box-shadow: 0 6px 20px rgba(76, 175, 80, 0.4);
transform: translateY(-3px);
}
.refresh-btn:active {
transform: translateY(-1px);
}
.btn-icon {
font-size: 1.1em;
transition: transform 0.3s ease;
}
.refresh-btn:hover .btn-icon {
transform: rotate(180deg);
}
/* 加载动画 */
.loading {
text-align: center;
padding: 60px 30px;
background: rgba(255, 255, 255, 0.95);
border-radius: 20px;
margin-bottom: 20px;
box-shadow: 0 8px 32px rgba(46, 125, 50, 0.1);
backdrop-filter: blur(15px);
}
.loading-content {
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
}
.spinner {
width: 50px;
height: 50px;
border: 5px solid #e8f5e8;
border-top: 5px solid #4caf50;
border-radius: 50%;
animation: spin 1s linear infinite;
position: relative;
}
.spinner::after {
content: '';
position: absolute;
top: -5px;
left: -5px;
right: -5px;
bottom: -5px;
border: 2px solid transparent;
border-top: 2px solid #81c784;
border-radius: 50%;
animation: spin 2s linear infinite reverse;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.loading-text {
display: flex;
flex-direction: column;
align-items: center;
gap: 15px;
}
.loading-emoji {
font-size: 2.5em;
animation: pulse 1.5s ease-in-out infinite alternate;
}
@keyframes pulse {
0% { transform: scale(1); opacity: 0.8; }
100% { transform: scale(1.1); opacity: 1; }
}
.loading-text p {
font-size: 1.1em;
color: #4caf50;
font-weight: 500;
margin: 0;
}
.loading-dots {
display: flex;
gap: 5px;
}
.loading-dots span {
width: 8px;
height: 8px;
background: #4caf50;
border-radius: 50%;
animation: dot-bounce 1.4s ease-in-out infinite both;
}
.loading-dots span:nth-child(1) { animation-delay: -0.32s; }
.loading-dots span:nth-child(2) { animation-delay: -0.16s; }
@keyframes dot-bounce {
0%, 80%, 100% { transform: scale(0.8); opacity: 0.5; }
40% { transform: scale(1.2); opacity: 1; }
}
/* 热搜列表 */
.hot-list {
display: grid;
gap: 20px;
animation: fadeInUp 0.6s ease-out;
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.hot-item {
background: rgba(255, 255, 255, 0.98);
border-radius: 16px;
padding: 25px;
box-shadow: 0 4px 20px rgba(46, 125, 50, 0.08);
transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
border: 1px solid rgba(76, 175, 80, 0.15);
backdrop-filter: blur(10px);
position: relative;
overflow: hidden;
animation: slideInLeft 0.6s ease-out;
animation-fill-mode: both;
}
.hot-item:nth-child(odd) {
animation-delay: 0.1s;
}
.hot-item:nth-child(even) {
animation-delay: 0.2s;
}
@keyframes slideInLeft {
from {
opacity: 0;
transform: translateX(-50px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
.hot-item::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 4px;
height: 100%;
background: linear-gradient(to bottom, #4caf50, #81c784);
transform: scaleY(0);
transition: transform 0.3s ease;
}
.hot-item:hover::before {
transform: scaleY(1);
}
.hot-item:hover {
box-shadow: 0 8px 40px rgba(46, 125, 50, 0.15);
transform: translateY(-5px) scale(1.02);
border-color: rgba(76, 175, 80, 0.3);
}
.hot-item-header {
display: flex;
align-items: center;
margin-bottom: 18px;
gap: 15px;
}
.hot-rank {
background: linear-gradient(135deg, #4caf50, #66bb6a);
color: white;
min-width: 40px;
height: 40px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
font-size: 1em;
flex-shrink: 0;
position: relative;
box-shadow: 0 3px 10px rgba(76, 175, 80, 0.3);
}
.hot-rank::after {
content: '';
position: absolute;
top: -2px;
left: -2px;
right: -2px;
bottom: -2px;
background: linear-gradient(45deg, #4caf50, #81c784, #4caf50);
border-radius: 50%;
z-index: -1;
opacity: 0;
transition: opacity 0.3s ease;
}
.hot-item:hover .hot-rank::after {
opacity: 0.7;
}
.hot-rank.top-3 {
background: linear-gradient(135deg, #ff6b35, #f7931e, #ffa726);
box-shadow: 0 3px 15px rgba(255, 107, 53, 0.4);
animation: glow 2s ease-in-out infinite alternate;
}
@keyframes glow {
0% { box-shadow: 0 3px 15px rgba(255, 107, 53, 0.4); }
100% { box-shadow: 0 3px 20px rgba(255, 107, 53, 0.6), 0 0 25px rgba(255, 107, 53, 0.3); }
}
.hot-rank.top-3::before {
content: '👑';
position: absolute;
top: -8px;
right: -5px;
font-size: 0.7em;
animation: crown-bounce 1s ease-in-out infinite alternate;
}
@keyframes crown-bounce {
0% { transform: translateY(0) rotate(-5deg); }
100% { transform: translateY(-2px) rotate(5deg); }
}
.hot-title {
font-size: 1.15em;
font-weight: 600;
color: #1b5e20;
flex: 1;
line-height: 1.4;
position: relative;
}
.hot-content {
display: flex;
gap: 18px;
align-items: flex-start;
}
.hot-cover {
width: 90px;
height: 90px;
border-radius: 12px;
object-fit: cover;
flex-shrink: 0;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.hot-cover::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(45deg, transparent 30%, rgba(255, 255, 255, 0.1) 50%, transparent 70%);
transform: translateX(-100%);
transition: transform 0.6s ease;
}
.hot-item:hover .hot-cover::after {
transform: translateX(100%);
}
.hot-item:hover .hot-cover {
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.15);
transform: scale(1.05);
}
.hot-info {
flex: 1;
display: flex;
flex-direction: column;
gap: 8px;
}
.hot-value {
color: #e91e63;
font-weight: 700;
font-size: 1.1em;
display: flex;
align-items: center;
gap: 6px;
}
.hot-value::before {
content: '热度';
font-size: 1.2em;
animation: fire 1.5s ease-in-out infinite alternate;
}
@keyframes fire {
0% { transform: scale(1); }
100% { transform: scale(1.1); }
}
.hot-time {
color: #757575;
font-size: 0.9em;
display: flex;
align-items: center;
gap: 6px;
}
.hot-time::before {
content: '📅日期';
font-size: 1em;
}
.hot-link {
display: inline-flex;
align-items: center;
gap: 6px;
color: #4caf50;
text-decoration: none;
font-size: 0.95em;
font-weight: 600;
padding: 8px 18px;
border: 2px solid #4caf50;
border-radius: 25px;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
max-width: fit-content;
}
.hot-link::before {
content: '👀';
font-size: 1em;
}
.hot-link::after {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(76, 175, 80, 0.2), transparent);
transition: left 0.5s ease;
}
.hot-link:hover::after {
left: 100%;
}
.hot-link:hover {
background: #4caf50;
color: white;
transform: scale(1.05);
box-shadow: 0 4px 15px rgba(76, 175, 80, 0.3);
}
/* 错误信息 */
.error-message {
text-align: center;
padding: 60px 30px;
background: rgba(255, 255, 255, 0.95);
border-radius: 20px;
box-shadow: 0 8px 32px rgba(211, 47, 47, 0.1);
backdrop-filter: blur(15px);
border: 1px solid rgba(255, 255, 255, 0.3);
}
.error-content {
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
}
.error-icon {
font-size: 4em;
animation: shake 1s ease-in-out infinite alternate;
}
@keyframes shake {
0% { transform: translateX(0); }
25% { transform: translateX(-5px) rotate(-5deg); }
50% { transform: translateX(5px) rotate(5deg); }
75% { transform: translateX(-3px) rotate(-3deg); }
100% { transform: translateX(0) rotate(0deg); }
}
.error-content h3 {
font-size: 1.5em;
color: #d32f2f;
margin: 0;
font-weight: 600;
}
.error-content p {
color: #757575;
font-size: 1em;
margin: 0;
line-height: 1.5;
}
.retry-btn {
background: linear-gradient(135deg, #4caf50, #66bb6a);
color: white;
border: none;
padding: 12px 25px;
border-radius: 25px;
cursor: pointer;
font-size: 1em;
font-weight: 600;
transition: all 0.3s ease;
box-shadow: 0 4px 15px rgba(76, 175, 80, 0.3);
display: inline-flex;
align-items: center;
gap: 8px;
}
.retry-btn:hover {
background: linear-gradient(135deg, #388e3c, #4caf50);
box-shadow: 0 6px 20px rgba(76, 175, 80, 0.4);
transform: translateY(-2px);
}
.retry-btn span {
font-size: 1.1em;
transition: transform 0.3s ease;
}
.retry-btn:hover span {
transform: rotate(180deg);
}
/* 平板端适配 (768px - 1024px) */
@media (min-width: 768px) and (max-width: 1024px) {
.container {
padding: 30px;
}
.header {
padding: 40px 30px;
}
.header-icon {
font-size: 3.5em;
}
.title {
font-size: 2.5em;
}
.subtitle {
font-size: 1.2em;
}
.hot-list {
grid-template-columns: repeat(auto-fit, minmax(450px, 1fr));
gap: 25px;
}
.hot-item {
padding: 30px;
}
.hot-cover {
width: 85px;
height: 85px;
}
.hot-rank {
min-width: 42px;
height: 42px;
font-size: 1.05em;
}
.hot-title {
font-size: 1.2em;
}
.hot-value {
font-size: 1.15em;
}
}
/* 电脑端适配 (1025px+) */
@media (min-width: 1025px) {
.container {
padding: 40px;
}
.header {
padding: 50px 40px;
margin-bottom: 50px;
}
.header-icon {
font-size: 4em;
}
.title {
font-size: 3.5em;
letter-spacing: 2px;
}
.subtitle {
font-size: 1.3em;
}
.hot-list {
grid-template-columns: repeat(auto-fit, minmax(550px, 1fr));
gap: 30px;
}
.hot-item {
padding: 35px;
}
.hot-rank {
min-width: 45px;
height: 45px;
font-size: 1.1em;
}
.hot-cover {
width: 110px;
height: 110px;
}
.hot-title {
font-size: 1.3em;
}
.hot-value {
font-size: 1.2em;
}
.hot-time {
font-size: 1em;
}
.hot-link {
font-size: 1em;
padding: 10px 20px;
}
/* 电脑端特殊效果 */
.hot-item:hover {
transform: translateY(-8px) scale(1.03);
}
.hot-item::after {
content: '';
position: absolute;
top: 50%;
right: 20px;
transform: translateY(-50%);
font-size: 1.5em;
opacity: 0;
transition: opacity 0.3s ease;
}
.hot-item:hover::after {
opacity: 0.3;
}
}
/* 手机端适配 (默认, 767px以下) */
@media (max-width: 767px) {
.container {
padding: 15px;
}
.header {
padding: 25px 20px;
margin-bottom: 25px;
}
.header-icon {
font-size: 2.5em;
}
.title {
font-size: 2.2em;
letter-spacing: 0.5px;
}
.subtitle {
font-size: 1em;
}
.update-time {
font-size: 0.9em;
padding: 6px 12px;
}
.refresh-btn {
padding: 10px 20px;
font-size: 0.9em;
}
.hot-item {
padding: 20px;
border-radius: 12px;
}
.hot-rank {
min-width: 35px;
height: 35px;
font-size: 0.9em;
}
.hot-title {
font-size: 1.05em;
line-height: 1.3;
}
.hot-content {
flex-direction: column;
gap: 15px;
}
.hot-cover {
width: 100%;
height: 180px;
align-self: center;
max-width: 280px;
border-radius: 10px;
}
.hot-info {
gap: 10px;
}
.hot-value {
font-size: 1.05em;
}
.hot-time {
font-size: 0.85em;
}
.hot-link {
font-size: 0.9em;
padding: 8px 16px;
align-self: flex-start;
}
/* 手机端动画优化 */
.hot-item {
animation-duration: 0.4s;
}
.hot-item:hover {
transform: translateY(-2px) scale(1.01);
}
}
/* 超小屏幕适配 (480px以下) */
@media (max-width: 480px) {
.container {
padding: 12px;
}
.header {
padding: 20px 15px;
margin-bottom: 20px;
}
.header-icon {
font-size: 2.2em;
}
.title {
font-size: 1.9em;
letter-spacing: 0.3px;
}
.subtitle {
font-size: 0.95em;
}
.update-time {
font-size: 0.85em;
padding: 5px 10px;
}
.refresh-btn {
padding: 8px 16px;
font-size: 0.85em;
}
.hot-list {
gap: 15px;
}
.hot-item {
padding: 18px 15px;
border-radius: 10px;
}
.hot-item-header {
margin-bottom: 15px;
gap: 12px;
}
.hot-rank {
min-width: 32px;
height: 32px;
font-size: 0.85em;
}
.hot-title {
font-size: 1em;
line-height: 1.25;
}
.hot-content {
gap: 12px;
}
.hot-cover {
height: 160px;
max-width: 260px;
border-radius: 8px;
}
.hot-info {
gap: 8px;
}
.hot-value {
font-size: 1em;
}
.hot-time {
font-size: 0.8em;
}
.hot-link {
font-size: 0.85em;
padding: 6px 14px;
}
/* 超小屏幕性能优化 */
.hot-item {
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.hot-item::before,
.hot-item::after,
.hot-cover::after,
.hot-link::after {
display: none;
}
.loading-content {
gap: 15px;
}
.loading-emoji {
font-size: 2em;
}
.loading-text p {
font-size: 1em;
}
.error-icon {
font-size: 3em;
}
.error-content h3 {
font-size: 1.3em;
}
.error-content p {
font-size: 0.9em;
}
}

View File

@@ -1,60 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>抖音热搜榜</title>
<link rel="stylesheet" href="css/background.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="container">
<header class="header">
<div class="header-icon">🔥</div>
<h1 class="title">📱 抖音热搜榜 🎵</h1>
<p class="subtitle">实时热门话题 · 紧跟潮流趋势</p>
<div class="update-time">
<span class="time-icon"></span>
<span id="updateTime">加载中...</span>
</div>
<button id="refreshBtn" class="refresh-btn">
<span class="btn-icon">🔄</span>
刷新数据
</button>
</header>
<div class="loading" id="loading">
<div class="loading-content">
<div class="spinner"></div>
<div class="loading-text">
<span class="loading-emoji">🎭</span>
<p>正在获取最新热搜...</p>
<div class="loading-dots">
<span></span>
<span></span>
<span></span>
</div>
</div>
</div>
</div>
<div class="hot-list" id="hotList">
<!-- 热搜列表将动态生成 -->
</div>
<div class="error-message" id="errorMessage" style="display: none;">
<div class="error-content">
<div class="error-icon">😵</div>
<h3>加载失败了</h3>
<p>网络连接出现问题,请稍后重试</p>
<button onclick="loadHotList()" class="retry-btn">
<span>🔄</span>
重新加载
</button>
</div>
</div>
</div>
<script src="js/script.js"></script>
</body>
</html>

View File

@@ -1,300 +0,0 @@
// API接口列表
const API_ENDPOINTS = [
"https://60s-cf.viki.moe",
"https://60s.viki.moe",
"https://60s.b23.run",
"https://60s.114128.xyz",
"https://60s-cf.114128.xyz"
];
// 当前使用的API索引
let currentApiIndex = 0;
// DOM元素
const loadingElement = document.getElementById('loading');
const hotListElement = document.getElementById('hotList');
const errorMessageElement = document.getElementById('errorMessage');
const updateTimeElement = document.getElementById('updateTime');
const refreshBtn = document.getElementById('refreshBtn');
// 页面加载完成后自动加载数据
document.addEventListener('DOMContentLoaded', function() {
loadHotList();
});
// 刷新按钮点击事件
refreshBtn.addEventListener('click', function() {
loadHotList();
});
// 加载热搜列表
async function loadHotList() {
showLoading();
hideError();
try {
const data = await fetchData();
displayHotList(data.data);
updateRefreshTime();
} catch (error) {
console.error('加载失败:', error);
showError();
}
hideLoading();
}
// 获取数据
async function fetchData() {
for (let i = 0; i < API_ENDPOINTS.length; i++) {
const apiUrl = API_ENDPOINTS[currentApiIndex];
try {
const response = await fetch(`${apiUrl}/v2/douyin`, {
method: 'GET',
headers: {
'Accept': 'application/json',
},
timeout: 10000
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
const data = await response.json();
if (data.code === 200 && data.data) {
return data;
} else {
throw new Error('数据格式错误');
}
} catch (error) {
console.error(`API ${apiUrl} 请求失败:`, error);
currentApiIndex = (currentApiIndex + 1) % API_ENDPOINTS.length;
if (i === API_ENDPOINTS.length - 1) {
throw new Error('所有API接口都无法访问');
}
}
}
}
// 显示热搜列表
function displayHotList(hotData) {
hotListElement.innerHTML = '';
hotData.forEach((item, index) => {
const hotItem = createHotItem(item, index + 1);
hotListElement.appendChild(hotItem);
});
}
// 创建热搜项目
function createHotItem(item, rank) {
const hotItem = document.createElement('div');
hotItem.className = 'hot-item';
const rankClass = rank <= 3 ? 'hot-rank top-3' : 'hot-rank';
const formattedHotValue = formatHotValue(item.hot_value);
const formattedTime = formatTime(item.event_time);
// 根据排名添加特殊标识
let rankEmoji = '';
if (rank === 1) rankEmoji = '🥇';
else if (rank === 2) rankEmoji = '🥈';
else if (rank === 3) rankEmoji = '🥉';
else if (rank <= 10) rankEmoji = '🔥';
else rankEmoji = '📈';
// 根据热度值添加火焰等级
let fireLevel = '';
if (item.hot_value >= 11000000) fireLevel = '🔥🔥🔥🔥🔥🔥🔥🔥🔥';
else if (item.hot_value >= 1000000) fireLevel = '🔥🔥🔥🔥🔥🔥🔥🔥';
else if (item.hot_value >= 9500000) fireLevel = '🔥🔥🔥🔥🔥🔥🔥';
else if (item.hot_value >= 9000000) fireLevel = '🔥🔥🔥🔥🔥🔥';
else if (item.hot_value >= 8000000) fireLevel = '🔥🔥🔥🔥🔥';
else if (item.hot_value >= 7000000) fireLevel = '🔥🔥🔥🔥';
else if (item.hot_value >= 6000000) fireLevel = '🔥🔥🔥';
else if (item.hot_value >= 5000000) fireLevel = '🔥🔥';
else fireLevel = '🔥';
hotItem.innerHTML = `
<div class="hot-item-header">
<div class="${rankClass}">${rank}</div>
<div class="hot-title">${rankEmoji} ${escapeHtml(item.title)}</div>
</div>
<div class="hot-content">
<img src="${item.cover}" alt="${escapeHtml(item.title)}" class="hot-cover" onerror="handleImageError(this)">
<div class="hot-info">
<div class="hot-value">${fireLevel} ${formattedHotValue}</div>
<div class="hot-time"> ${formattedTime}</div>
<a href="${item.link}" target="_blank" class="hot-link">
查看详情
</a>
</div>
</div>
`;
return hotItem;
}
// 格式化热度值
function formatHotValue(value) {
if (value >= 100000000) {
return (value / 100000000).toFixed(1) + '亿';
} else if (value >= 10000) {
return (value / 10000).toFixed(1) + '万';
} else {
return value.toLocaleString();
}
}
// 格式化时间
function formatTime(timeStr) {
try {
const formattedTime = timeStr.replace(/\//g, '-');
const date = new Date(formattedTime);
const now = new Date();
const diff = now - date;
const minutes = Math.floor(diff / (1000 * 60));
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);
if (days > 0) {
return `${days}天前`;
} else if (hours > 0) {
return `${hours}小时前`;
} else if (minutes > 0) {
return `${minutes}分钟前`;
} else {
return '刚刚';
}
} catch (error) {
return timeStr;
}
}
// HTML转义
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
// 图片加载错误处理
function handleImageError(img) {
img.src = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODAiIGhlaWdodD0iODAiIHZpZXdCb3g9IjAgMCA4MCA4MCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjgwIiBoZWlnaHQ9IjgwIiBmaWxsPSIjZjVmNWY1Ii8+CjxwYXRoIGQ9Ik00MCAyMEM0NCAyMCA0NyAyMyA0NyAyN1Y1M0M0NyA1NyA0NCA2MCA0MCA2MEgxNkMxMiA2MCA5IDU3IDkgNTNWMjdDOSAyMyAxMiAyMCAxNiAyMEg0MFoiIHN0cm9rZT0iI2NjY2NjYyIgc3Ryb2tlLXdpZHRoPSIyIi8+CjxjaXJjbGUgY3g9IjMzIiBjeT0iMzIiIHI9IjMiIGZpbGw9IiNjY2NjY2MiLz4KPHBhdGggZD0iTTEzIDQ4TDIzIDM4TDMzIDQ4TDQzIDM4TDUzIDQ4IiBzdHJva2U9IiNjY2NjY2MiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+Cjwvc3ZnPgo=';
img.alt = '图片加载失败';
}
// 更新刷新时间
function updateRefreshTime() {
const now = new Date();
const timeStr = now.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
});
updateTimeElement.textContent = `最后更新: ${timeStr}`;
// 添加成功提示
showSuccessMessage('🎉 数据已更新');
}
// 显示成功消息
function showSuccessMessage(message) {
// 移除之前的提示
const existingToast = document.querySelector('.success-toast');
if (existingToast) {
existingToast.remove();
}
const toast = document.createElement('div');
toast.className = 'success-toast';
toast.textContent = message;
toast.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
background: linear-gradient(135deg, #4caf50, #66bb6a);
color: white;
padding: 12px 20px;
border-radius: 25px;
box-shadow: 0 4px 20px rgba(76, 175, 80, 0.3);
z-index: 1000;
font-weight: 600;
font-size: 0.9em;
animation: slideIn 0.3s ease-out;
backdrop-filter: blur(10px);
`;
document.body.appendChild(toast);
// 3秒后自动移除
setTimeout(() => {
toast.style.animation = 'slideOut 0.3s ease-in forwards';
setTimeout(() => toast.remove(), 300);
}, 3000);
}
// 添加CSS动画到页面
if (!document.querySelector('#toast-styles')) {
const style = document.createElement('style');
style.id = 'toast-styles';
style.textContent = `
@keyframes slideIn {
from {
opacity: 0;
transform: translateX(100px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes slideOut {
from {
opacity: 1;
transform: translateX(0);
}
to {
opacity: 0;
transform: translateX(100px);
}
}
`;
document.head.appendChild(style);
}
// 显示加载状态
function showLoading() {
loadingElement.style.display = 'block';
hotListElement.style.display = 'none';
}
// 隐藏加载状态
function hideLoading() {
loadingElement.style.display = 'none';
hotListElement.style.display = 'block';
}
// 显示错误信息
function showError() {
errorMessageElement.style.display = 'block';
hotListElement.style.display = 'none';
}
// 隐藏错误信息
function hideError() {
errorMessageElement.style.display = 'none';
}
// 自动刷新 (每5分钟)
setInterval(function() {
loadHotList();
}, 5 * 60 * 1000);

View File

@@ -1,7 +0,0 @@
[
"https://60s-cf.viki.moe",
"https://60s.viki.moe",
"https://60s.b23.run",
"https://60s.114128.xyz",
"https://60s-cf.114128.xyz"
]

View File

@@ -1,496 +0,0 @@
{
"code": 200,
"message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s反馈群 595941841",
"data": [
{
"title": "九三阅兵具体安排公布",
"hot_value": 11821633,
"cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/oY1c972B7QzApGweaeQD3fGRo5aLIBrpCAuUSa~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=q01Se46GlLKYNv2klGKP1aM1cT0%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E4%B9%9D%E4%B8%89%E9%98%85%E5%85%B5%E5%85%B7%E4%BD%93%E5%AE%89%E6%8E%92%E5%85%AC%E5%B8%83",
"event_time": "2025/09/01 15:20:34",
"event_time_at": 1756711234,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "九月第一天",
"hot_value": 11327170,
"cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/oofTvDaDRCSs4hBFEFVJlAI9BBs0faZAc7IpGf~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=otkowVCSglk%2BS3tPrmBQFq6rIDw%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E4%B9%9D%E6%9C%88%E7%AC%AC%E4%B8%80%E5%A4%A9",
"event_time": "2025/09/01 07:28:57",
"event_time_at": 1756682937,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "遇见上合共享津彩",
"hot_value": 11222444,
"cover": "https://p11-sign.douyinpic.com/tos-cn-p-0015/oIJeINhBDBAiHADD4gi9Ae0CGALg1BqWI7vg0i~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=K%2BaEx5p%2BDv%2B1h3RgNnH0Yb9WT%2B8%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E9%81%87%E8%A7%81%E4%B8%8A%E5%90%88%E5%85%B1%E4%BA%AB%E6%B4%A5%E5%BD%A9",
"event_time": "2025/09/01 11:46:59",
"event_time_at": 1756698419,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "2025年开学第一课铭记与奋斗",
"hot_value": 11078403,
"cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/oA9NgVCRBABg7r70pQue8IzAUlfMaXf3hawOIB~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=3xYeXsD6JpXLDOVp6gYRxrvKFaM%3D&from=3218412987",
"link": "https://www.douyin.com/search/2025%E5%B9%B4%E5%BC%80%E5%AD%A6%E7%AC%AC%E4%B8%80%E8%AF%BE%E9%93%AD%E8%AE%B0%E4%B8%8E%E5%A5%8B%E6%96%97",
"event_time": "2025/09/01 11:21:13",
"event_time_at": 1756696873,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "石宇奇首夺世锦赛男单冠军",
"hot_value": 10395092,
"cover": "https://p11-sign.douyinpic.com/tos-cn-p-0015/oAf9IAlEuyE3lFiogfBuQFl8gDFqAoAHtFDNkE~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=tamoorhMGYhajvpmVNdX0TuUuZM%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E7%9F%B3%E5%AE%87%E5%A5%87%E9%A6%96%E5%A4%BA%E4%B8%96%E9%94%A6%E8%B5%9B%E7%94%B7%E5%8D%95%E5%86%A0%E5%86%9B",
"event_time": "2025/09/01 07:47:03",
"event_time_at": 1756684023,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "告别信息裸奔 国家网络身份认证来了",
"hot_value": 10255200,
"cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/oskNjrEUQIN9BBRCfeiDTGPE0geX0q6eAAyLr2~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=FrZQSxERPOBd6ktV8K%2Bt%2F3LgJ4A%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E5%91%8A%E5%88%AB%E4%BF%A1%E6%81%AF%E8%A3%B8%E5%A5%94%20%E5%9B%BD%E5%AE%B6%E7%BD%91%E7%BB%9C%E8%BA%AB%E4%BB%BD%E8%AE%A4%E8%AF%81%E6%9D%A5%E4%BA%86",
"event_time": "2025/09/01 10:28:41",
"event_time_at": 1756693721,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "记录我的开学第一天",
"hot_value": 9133236,
"cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015c000-ce/owTXhhk40MlJDQHi8P2B07AviaBqAL0VI9EQi~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=pTEfiV%2FfsmGuQxNllsV8PqT0RYc%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E8%AE%B0%E5%BD%95%E6%88%91%E7%9A%84%E5%BC%80%E5%AD%A6%E7%AC%AC%E4%B8%80%E5%A4%A9",
"event_time": "2025/09/01 12:43:33",
"event_time_at": 1756701813,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "9月起这些新规开始施行",
"hot_value": 9105252,
"cover": "https://p26-sign.douyinpic.com/tos-cn-p-0015/oEE9BseGagtA7JRBmzYA1aRMoCMAeIxfLFY5gA~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=YgH%2BJdVPmi76okIWTRoyEEZ3iDg%3D&from=3218412987",
"link": "https://www.douyin.com/search/9%E6%9C%88%E8%B5%B7%E8%BF%99%E4%BA%9B%E6%96%B0%E8%A7%84%E5%BC%80%E5%A7%8B%E6%96%BD%E8%A1%8C",
"event_time": "2025/09/01 11:48:01",
"event_time_at": 1756698481,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "李幼斌与李云龙跨时空对话",
"hot_value": 8998174,
"cover": "https://p26-sign.douyinpic.com/tos-cn-p-0015/oAarINBoAgRIPi9VTEMIfHeA11nDtF7hRDuGcA~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=3x7yTXHYKiIcnNJjznvZjCw%2FW94%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E6%9D%8E%E5%B9%BC%E6%96%8C%E4%B8%8E%E6%9D%8E%E4%BA%91%E9%BE%99%E8%B7%A8%E6%97%B6%E7%A9%BA%E5%AF%B9%E8%AF%9D",
"event_time": "2025/09/01 12:01:05",
"event_time_at": 1756699265,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "幼儿园第一天开学哀嚎一片",
"hot_value": 8962824,
"cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/osbXMAQYgIwwpkDCfeiDpGaE0gb9MXfeAAuLV2~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=w1l8V4VvjuO%2BvOvuQkXiEuXYko0%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E5%B9%BC%E5%84%BF%E5%9B%AD%E7%AC%AC%E4%B8%80%E5%A4%A9%E5%BC%80%E5%AD%A6%E5%93%80%E5%9A%8E%E4%B8%80%E7%89%87",
"event_time": "2025/09/01 11:05:01",
"event_time_at": 1756695901,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "田汉把国歌歌词写烟盒上系谣传",
"hot_value": 8930615,
"cover": "https://p3-sign.douyinpic.com/tos-cn-i-0813c001/ogA2AoCCXZMEAGF9f9QAlSACKRgfsC2oAFtIgD~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=7%2F8qsoQJd6TgpAEylOW1VyQrqeY%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E7%94%B0%E6%B1%89%E6%8A%8A%E5%9B%BD%E6%AD%8C%E6%AD%8C%E8%AF%8D%E5%86%99%E7%83%9F%E7%9B%92%E4%B8%8A%E7%B3%BB%E8%B0%A3%E4%BC%A0",
"event_time": "2025/09/01 13:51:28",
"event_time_at": 1756705888,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "苏超联赛积分榜",
"hot_value": 8838219,
"cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/o4vPLtWIQAaiggBRkQq5kw9ZlIVA0v1iDAILU~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=JJlPUPmWRzT3UPMenizW639pqVg%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E8%8B%8F%E8%B6%85%E8%81%94%E8%B5%9B%E7%A7%AF%E5%88%86%E6%A6%9C",
"event_time": "2025/08/31 22:01:53",
"event_time_at": 1756648913,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "一切正开始",
"hot_value": 8609507,
"cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015c000-ce/o8wN0EuXoETsyMz0ADCFFaAsFFTQeQf9fAublW~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=5I8uLkfpNYrGArQm%2BXLBa81NhYY%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E4%B8%80%E5%88%87%E6%AD%A3%E5%BC%80%E5%A7%8B",
"event_time": "2025/09/01 11:56:50",
"event_time_at": 1756699010,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "张玉宁为与球迷起冲突致歉",
"hot_value": 8511631,
"cover": "https://p11-sign.douyinpic.com/tos-cn-p-0015/oMfoIAFMN5GEWOzpBCDAQfaj7yRArCdByaEUfE~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=59ipMtNxZ8W3R5NNAJamlSOEbPo%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E5%BC%A0%E7%8E%89%E5%AE%81%E4%B8%BA%E4%B8%8E%E7%90%83%E8%BF%B7%E8%B5%B7%E5%86%B2%E7%AA%81%E8%87%B4%E6%AD%89",
"event_time": "2025/09/01 07:53:39",
"event_time_at": 1756684419,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "这一口会很疯狂",
"hot_value": 8454971,
"cover": "https://p26-sign.douyinpic.com/tos-cn-p-0015/oUIozRIBqC0ahA7FimIAmFEBeqDFfZK3Qfo8PE~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=ZBSuTMuu4678gSfReaVIfdK22J8%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E8%BF%99%E4%B8%80%E5%8F%A3%E4%BC%9A%E5%BE%88%E7%96%AF%E7%8B%82",
"event_time": "2025/09/01 10:36:16",
"event_time_at": 1756694176,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "邓超鹿晗合唱超级英雄",
"hot_value": 8357197,
"cover": "https://p11-sign.douyinpic.com/tos-cn-p-0015/oUBPIdtyQx0j8THRZAmZbyATihavQHI0niLIP~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=%2F66dsj8evHN94wNNFCn%2Bfhagee0%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E9%82%93%E8%B6%85%E9%B9%BF%E6%99%97%E5%90%88%E5%94%B1%E8%B6%85%E7%BA%A7%E8%8B%B1%E9%9B%84",
"event_time": "2025/09/01 07:45:11",
"event_time_at": 1756683911,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "伊萨克加盟利物浦",
"hot_value": 7963081,
"cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/ocAw2yaT4I99iDIPh9I3LaIiLBTnBASvH0Q1a~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=v4Gq0Iz87wyZ6lEYYOnKmaeur%2FM%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E4%BC%8A%E8%90%A8%E5%85%8B%E5%8A%A0%E7%9B%9F%E5%88%A9%E7%89%A9%E6%B5%A6",
"event_time": "2025/09/01 09:12:12",
"event_time_at": 1756689132,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "山东泰山6:0北京国安",
"hot_value": 7830358,
"cover": "https://p9-sign.douyinpic.com/tos-cn-p-0015/ogtA9BEEJZDJ9SgzBBLfFN0AflNDGoIAQ2I8A8~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=gu6O%2BhGDarr%2BHQe1P%2BHo9pUmBGU%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E5%B1%B1%E4%B8%9C%E6%B3%B0%E5%B1%B16%3A0%E5%8C%97%E4%BA%AC%E5%9B%BD%E5%AE%89",
"event_time": "2025/08/31 20:32:53",
"event_time_at": 1756643573,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "又到开学你包书皮了吗",
"hot_value": 7828995,
"cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/oUAwaPjCIiLAQI6ADQMAm06TBJxPJFAkCpIIi~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=aUkYTtkfaUKbK2DhznXU69sg8SU%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E5%8F%88%E5%88%B0%E5%BC%80%E5%AD%A6%E4%BD%A0%E5%8C%85%E4%B9%A6%E7%9A%AE%E4%BA%86%E5%90%97",
"event_time": "2025/08/31 17:04:09",
"event_time_at": 1756631049,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "樊振东德甲首秀两连败",
"hot_value": 7754365,
"cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/osOdEdibznClYwP0AABAIZW1eg0gbBmAzjiJfl~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=AyWBGXt%2FFFSp0QBM%2Bd5%2F9B4GPvo%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E6%A8%8A%E6%8C%AF%E4%B8%9C%E5%BE%B7%E7%94%B2%E9%A6%96%E7%A7%80%E4%B8%A4%E8%BF%9E%E8%B4%A5",
"event_time": "2025/09/01 07:16:58",
"event_time_at": 1756682218,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "为什么说00后的童年含金量高",
"hot_value": 7735122,
"cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/ogOQEQsnAACDBICh7LeFWRGCjeZneIB9I3oVFy~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=Htnqu7SupC%2FmvQpF2DDsLDh5FYA%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E4%B8%BA%E4%BB%80%E4%B9%88%E8%AF%B400%E5%90%8E%E7%9A%84%E7%AB%A5%E5%B9%B4%E5%90%AB%E9%87%91%E9%87%8F%E9%AB%98",
"event_time": "2025/08/31 16:38:30",
"event_time_at": 1756629510,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "刘宇千年直拍",
"hot_value": 7734149,
"cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015c000-ce/ostjBSmQ78E8estIXgFlHQxZQALRFfMepbTJWC~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=CPNw9h%2BpBB82qBykpuT11uMVFjo%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E5%88%98%E5%AE%87%E5%8D%83%E5%B9%B4%E7%9B%B4%E6%8B%8D",
"event_time": "2025/08/31 21:39:38",
"event_time_at": 1756647578,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "胡塞武装称将对以军袭击发起报复",
"hot_value": 7728698,
"cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/oseWgjCRBAfgft7c3QUm8JGApnYMaWdJdGj0SB~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=fX6AvTWQvNrihcvEraPHjJIS9iY%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E8%83%A1%E5%A1%9E%E6%AD%A6%E8%A3%85%E7%A7%B0%E5%B0%86%E5%AF%B9%E4%BB%A5%E5%86%9B%E8%A2%AD%E5%87%BB%E5%8F%91%E8%B5%B7%E6%8A%A5%E5%A4%8D",
"event_time": "2025/09/01 09:40:13",
"event_time_at": 1756690813,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "手把手教你手机变车机",
"hot_value": 7725104,
"cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/o47qAXUjDQN6KLr9AjFSCq92ZBf4okAQEfgSAp~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=OoNNciUVTOwZbl17IUYBOjFyBJ4%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E6%89%8B%E6%8A%8A%E6%89%8B%E6%95%99%E4%BD%A0%E6%89%8B%E6%9C%BA%E5%8F%98%E8%BD%A6%E6%9C%BA",
"event_time": "2025/09/01 11:15:15",
"event_time_at": 1756696515,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "莫迪与普京拥抱手拉手热聊",
"hot_value": 7723445,
"cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/oIaWAojVPLRUILGIyvvg1Sd1ZiLAKiCB6zQIX~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=u1IGnKz%2FAckLe%2BYFCQulFw0ioB8%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E8%8E%AB%E8%BF%AA%E4%B8%8E%E6%99%AE%E4%BA%AC%E6%8B%A5%E6%8A%B1%E6%89%8B%E6%8B%89%E6%89%8B%E7%83%AD%E8%81%8A",
"event_time": "2025/09/01 15:38:27",
"event_time_at": 1756712307,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "原来猪猪侠搞抽象领先我20年",
"hot_value": 7706786,
"cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/oINGyAfS2oFpfAgF2kYxEJAqTbSeEcgotfxeHv~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=S1Ve0ORP5%2BrHumx%2FK7uJbfm8PbM%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E5%8E%9F%E6%9D%A5%E7%8C%AA%E7%8C%AA%E4%BE%A0%E6%90%9E%E6%8A%BD%E8%B1%A1%E9%A2%86%E5%85%88%E6%88%9120%E5%B9%B4",
"event_time": "2025/09/01 10:52:59",
"event_time_at": 1756695179,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "北京国安就惨败道歉",
"hot_value": 7702358,
"cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/oYiXICjfn7uEi3AeK6W04BiXu3iBjigAAs9W0B~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=hgh%2Bfy4Ul82LWgXAL2hkIBMEpJM%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E5%8C%97%E4%BA%AC%E5%9B%BD%E5%AE%89%E5%B0%B1%E6%83%A8%E8%B4%A5%E9%81%93%E6%AD%89",
"event_time": "2025/09/01 09:21:10",
"event_time_at": 1756689670,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "港姐冠军陈咏诗是博士生",
"hot_value": 7702059,
"cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/okoRaMGvQBCI6KmVeBAAQ1eLEg1HK2foQuM7aB~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=5Lattu1v38oeQ8xGdXiDLcK4fwM%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E6%B8%AF%E5%A7%90%E5%86%A0%E5%86%9B%E9%99%88%E5%92%8F%E8%AF%97%E6%98%AF%E5%8D%9A%E5%A3%AB%E7%94%9F",
"event_time": "2025/09/01 10:47:23",
"event_time_at": 1756694843,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "王楚钦2:3徐瑛彬",
"hot_value": 7699514,
"cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/o00BTIi1ogMR8LBAiQdLmSaIPAuEyIQv1IP48~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=2%2BI5KkQpEugBkQcVCrSLgOtC088%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E7%8E%8B%E6%A5%9A%E9%92%A62%3A3%E5%BE%90%E7%91%9B%E5%BD%AC",
"event_time": "2025/08/31 21:21:08",
"event_time_at": 1756646468,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "王源 高音",
"hot_value": 7693290,
"cover": "https://p26-sign.douyinpic.com/tos-cn-p-0015/oYzDIaQiavwPRBUpanIkjAIWzwLCIgPkAyiOj~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=uXVN6xfkB3tz3iVo0DQuxqeaGk0%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E7%8E%8B%E6%BA%90%20%E9%AB%98%E9%9F%B3",
"event_time": "2025/08/31 20:30:04",
"event_time_at": 1756643404,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "俄乌在苏贾前线展开阵地争夺",
"hot_value": 7691808,
"cover": "https://p9-sign.douyinpic.com/tos-cn-p-0015/oo7iATIG8vA5hIIQBILB4oCgvygsUNzBS1aPi~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=SNzQbbxAJqqtdIkck9kvtRUJnZg%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E4%BF%84%E4%B9%8C%E5%9C%A8%E8%8B%8F%E8%B4%BE%E5%89%8D%E7%BA%BF%E5%B1%95%E5%BC%80%E9%98%B5%E5%9C%B0%E4%BA%89%E5%A4%BA",
"event_time": "2025/09/01 12:56:05",
"event_time_at": 1756702565,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "范丞丞温柔版一个人的夜变装",
"hot_value": 7689433,
"cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/oAPLWIAoR3CsXgVBuIQIRiTDyS14gaLPwELAi~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=yp9l95J9xlKf55IEP14P7sD7J%2F4%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E8%8C%83%E4%B8%9E%E4%B8%9E%E6%B8%A9%E6%9F%94%E7%89%88%E4%B8%80%E4%B8%AA%E4%BA%BA%E7%9A%84%E5%A4%9C%E5%8F%98%E8%A3%85",
"event_time": "2025/09/01 15:32:00",
"event_time_at": 1756711920,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "用美食致敬这场胜利",
"hot_value": 7681826,
"cover": "https://p11-sign.douyinpic.com/tos-cn-p-0015/oIFcUfHotAXxALhJEj2EK9SBNp0fQwKhAbCgQD~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=Dkuyg5REqCAMEIsp0Dr%2B%2BkAO%2BmQ%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E7%94%A8%E7%BE%8E%E9%A3%9F%E8%87%B4%E6%95%AC%E8%BF%99%E5%9C%BA%E8%83%9C%E5%88%A9",
"event_time": "2025/09/01 12:08:24",
"event_time_at": 1756699704,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "田曦薇猫猫本体藏不住了",
"hot_value": 7674729,
"cover": "https://p11-sign.douyinpic.com/tos-cn-p-0015c000-ce/oceyeLnbxAXFERxnPfLR2egAkYaXeRpHfhAQME~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=omEVZta%2FQeV%2FSBRNZ3%2BJF0iMXPQ%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E7%94%B0%E6%9B%A6%E8%96%87%E7%8C%AB%E7%8C%AB%E6%9C%AC%E4%BD%93%E8%97%8F%E4%B8%8D%E4%BD%8F%E4%BA%86",
"event_time": "2025/09/01 14:33:25",
"event_time_at": 1756708405,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "少年心气是不可再生之物",
"hot_value": 7673518,
"cover": "https://p3-sign.douyinpic.com/tos-cn-i-0813c001/oAUJIWFyAFCmtGpmAADAQis69JogkCFAA0Eqff~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=YHeldSJZXPEBMLF2i%2Bj%2Fc60oKsQ%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E5%B0%91%E5%B9%B4%E5%BF%83%E6%B0%94%E6%98%AF%E4%B8%8D%E5%8F%AF%E5%86%8D%E7%94%9F%E4%B9%8B%E7%89%A9",
"event_time": "2025/09/01 07:54:31",
"event_time_at": 1756684471,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "南通2:1战胜苏州",
"hot_value": 7670255,
"cover": "https://p11-sign.douyinpic.com/tos-cn-p-0015/o4WAaBigTGBaeBgrqm5Kir0Af6DGO0IAF6IQPA~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=uV2f%2FvbzU4Y9DfhXxnPBc3hOAxY%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E5%8D%97%E9%80%9A2%3A1%E6%88%98%E8%83%9C%E8%8B%8F%E5%B7%9E",
"event_time": "2025/08/31 18:02:42",
"event_time_at": 1756634562,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "起猛了差点以为入冬了",
"hot_value": 7669368,
"cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015c000-ce/ogA5HPw1xiIwS2szhaBPMZvC1P0LAPPQAigEZ~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=UQNTgz2vyL2UMvzVj2gzBmPbM2A%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E8%B5%B7%E7%8C%9B%E4%BA%86%E5%B7%AE%E7%82%B9%E4%BB%A5%E4%B8%BA%E5%85%A5%E5%86%AC%E4%BA%86",
"event_time": "2025/09/01 14:23:50",
"event_time_at": 1756707830,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "终于轮到我围观军训了",
"hot_value": 7655201,
"cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015c000-ce/oobwIeLUf4O7iiazJOGAQLZO7DRgCDCBLhI2ez~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=WQn5PvdzvIerbF%2B1iNjF3b6itqQ%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E7%BB%88%E4%BA%8E%E8%BD%AE%E5%88%B0%E6%88%91%E5%9B%B4%E8%A7%82%E5%86%9B%E8%AE%AD%E4%BA%86",
"event_time": "2025/08/31 13:09:34",
"event_time_at": 1756616974,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "金铲铲陪伴是李现最长情的告白",
"hot_value": 7653496,
"cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015c000-ce/oYPAKIM2vpBnPULXOmBbAEac6KzbOhSiILiLP~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=rsA7DcONzMySFGRNa4PMk6ftyBk%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E9%87%91%E9%93%B2%E9%93%B2%E9%99%AA%E4%BC%B4%E6%98%AF%E6%9D%8E%E7%8E%B0%E6%9C%80%E9%95%BF%E6%83%85%E7%9A%84%E5%91%8A%E7%99%BD",
"event_time": "2025/08/31 22:58:48",
"event_time_at": 1756652328,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "张予曦妈妈不介意女儿谈姐弟恋",
"hot_value": 7650811,
"cover": "https://p11-sign.douyinpic.com/tos-cn-p-0015/oEB5A1NsLFeadA9HQoED9TfmQ8jHgUPxACzjw9~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=KF3nedfpt5iPcUZ%2Fv9SyYI0ZSWg%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E5%BC%A0%E4%BA%88%E6%9B%A6%E5%A6%88%E5%A6%88%E4%B8%8D%E4%BB%8B%E6%84%8F%E5%A5%B3%E5%84%BF%E8%B0%88%E5%A7%90%E5%BC%9F%E6%81%8B",
"event_time": "2025/08/31 17:44:23",
"event_time_at": 1756633463,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "边伯贤也来刀马刀马了",
"hot_value": 7650164,
"cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/ogfBltLZDIGmRGCAseKAeaIBRnQH79gBGOb4kC~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=nLrGTCoyqEGU882IYRhJOStMdpg%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E8%BE%B9%E4%BC%AF%E8%B4%A4%E4%B9%9F%E6%9D%A5%E5%88%80%E9%A9%AC%E5%88%80%E9%A9%AC%E4%BA%86",
"event_time": "2025/08/31 13:44:44",
"event_time_at": 1756619084,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "金靖演绎甜美女孩",
"hot_value": 7649913,
"cover": "https://p11-sign.douyinpic.com/tos-cn-p-0015/o0cBcsRQjiGGFCOOArGzzeIfLBA7FEYojeKwGQ~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=9BY7gGsW39uBcs06t%2BrXTCQ5J5k%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E9%87%91%E9%9D%96%E6%BC%94%E7%BB%8E%E7%94%9C%E7%BE%8E%E5%A5%B3%E5%AD%A9",
"event_time": "2025/08/31 19:00:32",
"event_time_at": 1756638032,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "一口气看日本如何造出反华体制",
"hot_value": 7648850,
"cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/oUoyIxcAADE55goYWdhBfFF4HACpRIpy9Xse6K~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=xjjRJGl0AzxkaEnOiVrzRx1hoZ8%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E4%B8%80%E5%8F%A3%E6%B0%94%E7%9C%8B%E6%97%A5%E6%9C%AC%E5%A6%82%E4%BD%95%E9%80%A0%E5%87%BA%E5%8F%8D%E5%8D%8E%E4%BD%93%E5%88%B6",
"event_time": "2025/08/30 21:50:31",
"event_time_at": 1756561831,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "张艺兴真空西装跳狼与美女",
"hot_value": 7646868,
"cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015c000-ce/o4YKfLEIEEwo5stfDSFe0s2TFRjxXAAZDCE9Bl~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=gqBuLvszd8eew81uXP8rf7idtog%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E5%BC%A0%E8%89%BA%E5%85%B4%E7%9C%9F%E7%A9%BA%E8%A5%BF%E8%A3%85%E8%B7%B3%E7%8B%BC%E4%B8%8E%E7%BE%8E%E5%A5%B3",
"event_time": "2025/08/31 22:12:44",
"event_time_at": 1756649564,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "罗永浩对谈脱口秀新王何广智",
"hot_value": 7644688,
"cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/okQ0qo1AKBQP3g981qQA1FEAzGDYjtFFdfYVeD~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=Mg24ss6tlv%2FY%2B%2B9PS5UdijEG1Dw%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E7%BD%97%E6%B0%B8%E6%B5%A9%E5%AF%B9%E8%B0%88%E8%84%B1%E5%8F%A3%E7%A7%80%E6%96%B0%E7%8E%8B%E4%BD%95%E5%B9%BF%E6%99%BA",
"event_time": "2025/09/01 13:56:14",
"event_time_at": 1756706174,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "周深的刀马刀马好可爱",
"hot_value": 7644052,
"cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/osAPL0laAbWHtEmVBUIKMQDypItTiF3HI0PQi~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=qcK3K8uko38iBuRXDg4uCTaqEPc%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E5%91%A8%E6%B7%B1%E7%9A%84%E5%88%80%E9%A9%AC%E5%88%80%E9%A9%AC%E5%A5%BD%E5%8F%AF%E7%88%B1",
"event_time": "2025/08/31 18:31:56",
"event_time_at": 1756636316,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "杜克一哥的对话太好哭了",
"hot_value": 7639907,
"cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/oofoeQ9VAPDsphKEAiFQbQwCAEwoQgBpLtBC0A~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=wulyNlwPrSoIJu1JKBdKpE142mA%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E6%9D%9C%E5%85%8B%E4%B8%80%E5%93%A5%E7%9A%84%E5%AF%B9%E8%AF%9D%E5%A4%AA%E5%A5%BD%E5%93%AD%E4%BA%86",
"event_time": "2025/08/30 21:17:58",
"event_time_at": 1756559878,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "外媒全景记录普京抵华现场",
"hot_value": 7637541,
"cover": "https://p3-sign.douyinpic.com/tos-cn-p-0015/oIGC9LxDIQ6QAI1fG1eEipfA2eZjiGInCHFFEJ~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=HiKj%2FiLGiaN2D5GdS5OlAISbGHo%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E5%A4%96%E5%AA%92%E5%85%A8%E6%99%AF%E8%AE%B0%E5%BD%95%E6%99%AE%E4%BA%AC%E6%8A%B5%E5%8D%8E%E7%8E%B0%E5%9C%BA",
"event_time": "2025/09/01 11:59:34",
"event_time_at": 1756699174,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
},
{
"title": "赵丽颖工作室明兰代班营业",
"hot_value": 7635755,
"cover": "https://p26-sign.douyinpic.com/tos-cn-p-0015c000-ce/oIhHELPBeI6Ieb0A9OpCuWXh0CAAgiuniEweIw~noop.jpeg?lk3s=bfd515bb&x-expires=1756735200&x-signature=xmQOeLdWN4FaeZjFBqtMQuctYv8%3D&from=3218412987",
"link": "https://www.douyin.com/search/%E8%B5%B5%E4%B8%BD%E9%A2%96%E5%B7%A5%E4%BD%9C%E5%AE%A4%E6%98%8E%E5%85%B0%E4%BB%A3%E7%8F%AD%E8%90%A5%E4%B8%9A",
"event_time": "2025/08/31 20:52:34",
"event_time_at": 1756644754,
"active_time": "2025-09-01 16:46:46",
"active_time_at": 1756745206000
}
]
}

View File

@@ -1,495 +0,0 @@
/* 猫眼票房排行榜 - 淡绿色清新风格样式 */
/* 重置样式 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #a8e6cf 0%, #dcedc1 50%, #ffd3a5 100%);
min-height: 100vh;
color: #2d5016;
line-height: 1.6;
overflow-x: hidden;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
/* 头部样式 */
.header {
text-align: center;
margin-bottom: 30px;
background: rgba(255, 255, 255, 0.85);
border-radius: 20px;
padding: 30px;
box-shadow: 0 8px 25px rgba(45, 80, 22, 0.08);
backdrop-filter: blur(10px);
}
.header h1 {
font-size: 2.5rem;
color: #2d5016;
margin-bottom: 10px;
font-weight: 700;
display: flex;
align-items: center;
justify-content: center;
gap: 15px;
}
.header p {
color: #5a7c65;
font-size: 1.1rem;
}
/* 加载状态 */
.loading {
text-align: center;
padding: 40px;
background: rgba(255, 255, 255, 0.85);
border-radius: 15px;
box-shadow: 0 5px 20px rgba(45, 80, 22, 0.08);
}
.spinner {
width: 40px;
height: 40px;
border: 4px solid #e8f5e8;
border-top: 4px solid #81c784;
border-radius: 50%;
animation: spin 1s linear infinite;
margin: 0 auto 20px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* 票房排行榜容器 */
.ranking-container {
background: rgba(255, 255, 255, 0.85);
border-radius: 20px;
padding: 30px;
box-shadow: 0 8px 25px rgba(45, 80, 22, 0.08);
backdrop-filter: blur(10px);
margin-bottom: 20px;
}
/* 排行榜标题 */
.ranking-title {
text-align: center;
font-size: 1.8rem;
font-weight: 700;
color: #2d5016;
margin-bottom: 25px;
}
/* 票房排行榜列表 */
.movie-list {
display: grid;
gap: 15px;
}
/* 电影项目 */
.movie-item {
background: rgba(255, 255, 255, 0.9);
border-radius: 15px;
padding: 20px;
box-shadow: 0 4px 15px rgba(45, 80, 22, 0.05);
transition: all 0.3s ease;
border-left: 5px solid transparent;
position: relative;
overflow: hidden;
}
.movie-item:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(45, 80, 22, 0.12);
}
/* 前三名特殊样式 */
.movie-item.top-1 {
border-left-color: #ffd700;
background: linear-gradient(135deg, rgba(255, 215, 0, 0.1) 0%, rgba(255, 255, 255, 0.9) 100%);
}
.movie-item.top-2 {
border-left-color: #c0c0c0;
background: linear-gradient(135deg, rgba(192, 192, 192, 0.1) 0%, rgba(255, 255, 255, 0.9) 100%);
}
.movie-item.top-3 {
border-left-color: #cd7f32;
background: linear-gradient(135deg, rgba(205, 127, 50, 0.1) 0%, rgba(255, 255, 255, 0.9) 100%);
}
/* 排名徽章 */
.rank-badge {
position: absolute;
top: -10px;
right: -10px;
width: 50px;
height: 50px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
font-size: 1.2rem;
color: white;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
}
.rank-badge.gold {
background: linear-gradient(135deg, #ffd700, #ffed4a);
}
.rank-badge.silver {
background: linear-gradient(135deg, #c0c0c0, #e2e8f0);
}
.rank-badge.bronze {
background: linear-gradient(135deg, #cd7f32, #d69e2e);
}
.rank-badge.regular {
background: linear-gradient(135deg, #81c784, #66bb6a);
}
/* 电影信息布局 */
.movie-info {
display: grid;
grid-template-columns: auto 1fr auto;
align-items: center;
gap: 20px;
}
.rank-number {
font-size: 2rem;
font-weight: bold;
color: #2d5016;
min-width: 60px;
}
.movie-details {
flex: 1;
}
.movie-name {
font-size: 1.3rem;
font-weight: 700;
color: #2d5016;
margin-bottom: 5px;
}
.movie-year {
color: #5a7c65;
font-size: 0.95rem;
margin-bottom: 8px;
}
.box-office {
text-align: right;
}
.box-office-amount {
font-size: 1.4rem;
font-weight: bold;
color: #1b5e20;
margin-bottom: 3px;
}
.box-office-desc {
color: #5a7c65;
font-size: 0.9rem;
}
/* 统计信息 */
.stats-container {
background: rgba(255, 255, 255, 0.85);
border-radius: 15px;
padding: 20px;
margin-bottom: 20px;
box-shadow: 0 5px 20px rgba(45, 80, 22, 0.08);
backdrop-filter: blur(10px);
}
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
text-align: center;
}
.stat-item {
background: rgba(129, 199, 132, 0.1);
border-radius: 10px;
padding: 15px;
}
.stat-value {
font-size: 1.5rem;
font-weight: bold;
color: #2d5016;
}
.stat-label {
color: #5a7c65;
font-size: 0.9rem;
margin-top: 5px;
}
/* 更新时间 */
.update-time {
text-align: center;
color: #5a7c65;
font-size: 0.9rem;
margin-top: 20px;
padding: 15px;
background: rgba(255, 255, 255, 0.7);
border-radius: 10px;
}
/* 错误提示 */
.error {
text-align: center;
padding: 40px;
background: rgba(255, 255, 255, 0.85);
border-radius: 15px;
box-shadow: 0 5px 20px rgba(45, 80, 22, 0.08);
}
.error h3 {
color: #d32f2f;
margin-bottom: 15px;
font-size: 1.5rem;
}
.error p {
color: #5a7c65;
margin-bottom: 10px;
}
/* 动画效果 */
.fade-in {
animation: fadeIn 0.6s ease-in-out;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* 平板端适配 (768px - 1024px) */
@media screen and (max-width: 1024px) and (min-width: 768px) {
.container {
padding: 15px;
}
.header h1 {
font-size: 2.2rem;
}
.ranking-container {
padding: 25px;
}
.movie-info {
gap: 15px;
}
.rank-number {
font-size: 1.8rem;
min-width: 50px;
}
.movie-name {
font-size: 1.2rem;
}
.box-office-amount {
font-size: 1.3rem;
}
}
/* 手机端适配 (最大767px) - 优先优化 */
@media screen and (max-width: 767px) {
.container {
padding: 10px;
}
.header {
padding: 20px;
margin-bottom: 20px;
}
.header h1 {
font-size: 1.8rem;
flex-direction: column;
gap: 10px;
}
.header p {
font-size: 1rem;
}
.ranking-container {
padding: 20px 15px;
margin-bottom: 15px;
}
.ranking-title {
font-size: 1.5rem;
margin-bottom: 20px;
}
.movie-item {
padding: 15px;
margin-bottom: 10px;
}
.movie-info {
grid-template-columns: 50px 1fr;
grid-template-rows: auto auto;
gap: 10px;
}
.rank-number {
font-size: 1.5rem;
min-width: 40px;
grid-row: 1 / 3;
}
.movie-details {
grid-column: 2;
grid-row: 1;
}
.box-office {
grid-column: 2;
grid-row: 2;
text-align: left;
margin-top: 8px;
}
.movie-name {
font-size: 1.1rem;
margin-bottom: 3px;
}
.movie-year {
font-size: 0.85rem;
margin-bottom: 5px;
}
.box-office-amount {
font-size: 1.2rem;
}
.box-office-desc {
font-size: 0.85rem;
}
.rank-badge {
width: 40px;
height: 40px;
font-size: 1rem;
top: -8px;
right: -8px;
}
.stats-grid {
grid-template-columns: 1fr;
gap: 15px;
}
.stat-item {
padding: 12px;
}
.stat-value {
font-size: 1.3rem;
}
.update-time {
padding: 12px;
font-size: 0.85rem;
}
}
/* 小屏手机适配 (最大480px) */
@media screen and (max-width: 480px) {
.container {
padding: 8px;
}
.header {
padding: 15px;
}
.header h1 {
font-size: 1.6rem;
}
.ranking-container {
padding: 15px 10px;
}
.movie-item {
padding: 12px;
}
.movie-name {
font-size: 1rem;
}
.box-office-amount {
font-size: 1.1rem;
}
.rank-number {
font-size: 1.3rem;
min-width: 35px;
}
}
/* 高分辨率显示器优化 */
@media screen and (min-width: 1440px) {
.container {
max-width: 1400px;
}
.header h1 {
font-size: 3rem;
}
.movie-list {
gap: 20px;
}
.movie-item {
padding: 25px;
}
.movie-name {
font-size: 1.4rem;
}
.box-office-amount {
font-size: 1.5rem;
}
}

View File

@@ -1,40 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="猫眼票房排行榜 - 展示全球电影总票房排行榜">
<meta name="keywords" content="猫眼, 票房, 排行榜, 电影票房, 全球票房">
<title>猫眼票房排行榜 | 全球电影总票房</title>
<!-- 引入CSS样式 -->
<link rel="stylesheet" href="css/style.css">
<!-- 网站图标SVG内联为data URL避免外部依赖 -->
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🎬</text></svg>">
</head>
<body>
<div class="container">
<!-- 页面头部 -->
<header class="header">
<h1>
<span>🎬</span>
猫眼票房排行榜(时更)
</h1>
<p>展示全球电影总票房排行榜,数据来自权威源头,稳定实时</p>
</header>
<!-- 加载状态 -->
<div id="loading" class="loading">
<div class="spinner"></div>
<p>正在加载票房数据...</p>
</div>
<!-- 内容区域 -->
<main id="ranking-content" class="content" style="display: none;"></main>
</div>
<!-- 引入JavaScript -->
<script src="js/script.js"></script>
</body>
</html>

View File

@@ -1,249 +0,0 @@
// 猫眼票房排行榜 - JavaScript 实现
const API = {
endpoints: [],
currentIndex: 0,
params: {
encoding: 'json'
},
localFallback: '返回接口.json',
// 初始化API接口列表
async init() {
try {
const res = await fetch('./接口集合.json');
const endpoints = await res.json();
this.endpoints = endpoints.map(endpoint => `${endpoint}/v2/maoyan`);
} catch (e) {
// 如果无法加载接口集合,使用默认接口
this.endpoints = ['https://60s.viki.moe/v2/maoyan'];
}
},
// 获取当前接口URL
getCurrentUrl() {
if (this.endpoints.length === 0) return null;
const url = new URL(this.endpoints[this.currentIndex]);
Object.entries(this.params).forEach(([k, v]) => url.searchParams.append(k, v));
return url.toString();
},
// 切换到下一个接口
switchToNext() {
this.currentIndex = (this.currentIndex + 1) % this.endpoints.length;
return this.currentIndex < this.endpoints.length;
},
// 重置到第一个接口
reset() {
this.currentIndex = 0;
}
};
let elements = {};
// 初始化
window.addEventListener('DOMContentLoaded', () => {
initElements();
loadMaoyanList();
});
function initElements() {
elements = {
container: document.getElementById('ranking-content'),
loading: document.getElementById('loading'),
updateTime: document.getElementById('api-update-time'),
statsTotal: document.getElementById('stats-total'),
statsTop10: document.getElementById('stats-top10')
};
}
async function loadMaoyanList() {
try {
showLoading(true);
// 优先从线上API请求
let data = await fetchFromAPI();
// 如果线上失败,尝试从本地返回接口.json加载
if (!data) {
data = await fetchFromLocal();
}
if (!data || data.code !== 200 || !data.data) {
throw new Error(data && data.message ? data.message : '未能获取到有效数据');
}
renderRanking(data.data);
} catch (error) {
console.error('加载排行榜失败:', error);
showError(error.message || '加载失败,请稍后重试');
} finally {
showLoading(false);
}
}
async function fetchFromAPI() {
// 初始化API接口列表
await API.init();
// 重置API索引到第一个接口
API.reset();
// 尝试所有API接口
for (let i = 0; i < API.endpoints.length; i++) {
try {
const url = API.getCurrentUrl();
console.log(`尝试接口 ${i + 1}/${API.endpoints.length}: ${url}`);
const resp = await fetch(url, {
cache: 'no-store',
timeout: 10000 // 10秒超时
});
if (!resp.ok) {
throw new Error(`HTTP ${resp.status}: ${resp.statusText}`);
}
const data = await resp.json();
if (data && data.code === 200) {
console.log(`接口 ${i + 1} 请求成功`);
return data;
}
throw new Error(data && data.message ? data.message : '接口返回异常');
} catch (e) {
console.warn(`接口 ${i + 1} 失败:`, e.message);
// 如果不是最后一个接口,切换到下一个
if (i < API.endpoints.length - 1) {
API.switchToNext();
continue;
}
// 所有接口都失败了
console.warn('所有远程接口都失败,尝试本地数据');
return null;
}
}
}
async function fetchFromLocal() {
try {
const resp = await fetch(API.localFallback + `?t=${Date.now()}`);
if (!resp.ok) throw new Error(`本地文件HTTP ${resp.status}`);
const data = await resp.json();
return data;
} catch (e) {
console.error('读取本地返回接口.json失败:', e);
return null;
}
}
function renderRanking(payload) {
const { list = [], tip = '', update_time = '', update_time_at } = payload || {};
// 更新时间
if (elements.updateTime) {
elements.updateTime.textContent = update_time ? `更新时间:${update_time}` : '';
}
// 统计信息
if (elements.statsTotal) {
elements.statsTotal.textContent = list.length;
}
if (elements.statsTop10) {
elements.statsTop10.textContent = Math.min(10, list.length);
}
// 渲染列表
const html = `
<section class="stats-container">
<div class="stats-grid">
<div class="stat-item">
<div class="stat-value" id="stats-total">${list.length}</div>
<div class="stat-label">入榜影片数量</div>
</div>
<div class="stat-item">
<div class="stat-value" id="stats-top10">${Math.min(10, list.length)}</div>
<div class="stat-label">TOP10 数量</div>
</div>
</div>
</section>
<section class="ranking-container">
<h2 class="ranking-title">全球电影总票房排行榜</h2>
<div class="movie-list">
${list.map(item => renderMovieItem(item)).join('')}
</div>
</section>
${tip ? `<div class="update-time">${escapeHtml(tip)}</div>` : ''}
${update_time ? `<div class="update-time" id="api-update-time">更新时间:${escapeHtml(update_time)}</div>` : ''}
`;
elements.container.innerHTML = html;
elements.container.classList.add('fade-in');
}
function renderMovieItem(item) {
const rank = item.rank;
const cls = rank === 1 ? 'top-1' : rank === 2 ? 'top-2' : rank === 3 ? 'top-3' : '';
const badgeCls = rank === 1 ? 'gold' : rank === 2 ? 'silver' : rank === 3 ? 'bronze' : 'regular';
return `
<div class="movie-item ${cls}">
<div class="rank-badge ${badgeCls}">${rank}</div>
<div class="movie-info">
<div class="rank-number">#${rank}</div>
<div class="movie-details">
<div class="movie-name">${escapeHtml(item.movie_name)}</div>
<div class="movie-year">上映年份:${escapeHtml(item.release_year || '')}</div>
</div>
<div class="box-office">
<div class="box-office-amount">${formatCurrencyDesc(item.box_office_desc, item.box_office)}</div>
<div class="box-office-desc">总票房</div>
</div>
</div>
</div>
`;
}
function formatCurrencyDesc(desc, num) {
if (desc && typeof desc === 'string' && desc.trim()) return desc;
if (typeof num === 'number') {
// 人民币按亿元显示
if (num >= 1e8) return (num / 1e8).toFixed(2) + '亿元';
if (num >= 1e4) return (num / 1e4).toFixed(2) + '万元';
return num.toLocaleString('zh-CN') + '元';
}
return '—';
}
function showLoading(show) {
if (elements.loading) elements.loading.style.display = show ? 'block' : 'none';
if (elements.container) elements.container.style.display = show ? 'none' : 'block';
}
function showError(message) {
if (!elements.container) return;
elements.container.innerHTML = `
<div class="error">
<h3>⚠️ 加载失败</h3>
<p>${escapeHtml(message)}</p>
<p>请稍后重试</p>
</div>
`;
elements.container.style.display = 'block';
}
function escapeHtml(text) {
if (text == null) return '';
const div = document.createElement('div');
div.textContent = String(text);
return div.innerHTML;
}
// 键盘刷新快捷键 Ctrl/Cmd + R 刷新数据区域(不刷新整页)
window.addEventListener('keydown', (e) => {
if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 'r') {
e.preventDefault();
loadMaoyanList();
}
});

View File

@@ -1,7 +0,0 @@
[
"https://60s-cf.viki.moe",
"https://60s.viki.moe",
"https://60s.b23.run",
"https://60s.114128.xyz",
"https://60s-cf.114128.xyz"
]

View File

@@ -1,171 +0,0 @@
{
"code": 200,
"message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s反馈群 595941841",
"data": {
"list": [
{
"rank": 1,
"maoyan_id": 243,
"movie_name": "阿凡达",
"release_year": "2009",
"box_office": 21200972239,
"box_office_desc": "212.01亿元"
},
{
"rank": 2,
"maoyan_id": 248172,
"movie_name": "复仇者联盟 4终局之战",
"release_year": "2019",
"box_office": 20299852689,
"box_office_desc": "203亿元"
},
{
"rank": 3,
"maoyan_id": 78461,
"movie_name": "阿凡达:水之道",
"release_year": "2022",
"box_office": 16825062887,
"box_office_desc": "168.25亿元"
},
{
"rank": 4,
"maoyan_id": 267,
"movie_name": "泰坦尼克号",
"release_year": "1997",
"box_office": 16423064756,
"box_office_desc": "164.23亿元"
},
{
"rank": 5,
"maoyan_id": 1294273,
"movie_name": "哪吒之魔童闹海",
"release_year": "2025",
"box_office": 15908714214,
"box_office_desc": "159.09亿元"
},
{
"rank": 6,
"maoyan_id": 78536,
"movie_name": "星球大战:原力觉醒",
"release_year": "2015",
"box_office": 15019898914,
"box_office_desc": "150.2亿元"
},
{
"rank": 7,
"maoyan_id": 248170,
"movie_name": "复仇者联盟 3无限战争",
"release_year": "2018",
"box_office": 14882882413,
"box_office_desc": "148.83亿元"
},
{
"rank": 8,
"maoyan_id": 1254435,
"movie_name": "蜘蛛侠:英雄无归",
"release_year": "2021",
"box_office": 14160042137,
"box_office_desc": "141.6亿元"
},
{
"rank": 9,
"maoyan_id": 1479534,
"movie_name": "头脑特工队 2",
"release_year": "2024",
"box_office": 12319141075,
"box_office_desc": "123.19亿元"
},
{
"rank": 10,
"maoyan_id": 78602,
"movie_name": "侏罗纪世界",
"release_year": "2015",
"box_office": 12120986621,
"box_office_desc": "121.21亿元"
},
{
"rank": 11,
"maoyan_id": 1189879,
"movie_name": "狮子王",
"release_year": "2019",
"box_office": 12051977766,
"box_office_desc": "120.52亿元"
},
{
"rank": 12,
"maoyan_id": 262,
"movie_name": "复仇者联盟",
"release_year": "2012",
"box_office": 11026033139,
"box_office_desc": "110.26亿元"
},
{
"rank": 13,
"maoyan_id": 78405,
"movie_name": "速度与激情 7",
"release_year": "2015",
"box_office": 10988354292,
"box_office_desc": "109.88亿元"
},
{
"rank": 14,
"maoyan_id": 341152,
"movie_name": "壮志凌云 2独行侠",
"release_year": "2022",
"box_office": 10845892091,
"box_office_desc": "108.46亿元"
},
{
"rank": 15,
"maoyan_id": 247949,
"movie_name": "冰雪奇缘 2",
"release_year": "2019",
"box_office": 10541240357,
"box_office_desc": "105.41亿元"
},
{
"rank": 16,
"maoyan_id": 344942,
"movie_name": "芭比",
"release_year": "2023",
"box_office": 10493054406,
"box_office_desc": "104.93亿元"
},
{
"rank": 17,
"maoyan_id": 78429,
"movie_name": "复仇者联盟 2奥创纪元",
"release_year": "2015",
"box_office": 10188347873,
"box_office_desc": "101.88亿元"
},
{
"rank": 18,
"maoyan_id": 1250896,
"movie_name": "超级马里奥兄弟大电影",
"release_year": "2023",
"box_office": 9868050757,
"box_office_desc": "98.68亿元"
},
{
"rank": 19,
"maoyan_id": 341138,
"movie_name": "黑豹",
"release_year": "2018",
"box_office": 9788853998,
"box_office_desc": "97.89亿元"
},
{
"rank": 20,
"maoyan_id": 916,
"movie_name": "哈利・波特与死亡圣器(下)",
"release_year": "2011",
"box_office": 9735002643,
"box_office_desc": "97.35亿元"
}
],
"tip": "注:内地票房数据实时更新,包括点映及预售票房。港澳台及海外票房为统计数据,每小时更新。汇率采用 2025年1月31日市场汇率1美元≈7.2514人民币",
"update_time": "2025/08/19 14:41:34",
"update_time_at": 1755585694385
}
}

View File

@@ -1,7 +0,0 @@
[
"https://60s-cf.viki.moe",
"https://60s.viki.moe",
"https://60s.b23.run",
"https://60s.114128.xyz",
"https://60s-cf.114128.xyz"
]

View File

@@ -1,750 +0,0 @@
{
"code": 200,
"message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s反馈群 595941841",
"data": [
{
"id": 19723756,
"name": "飙升榜",
"description": "云音乐中每天热度上升最快的100首单曲每日更新。",
"cover": "https://p1.music.126.net/rIi7Qzy2i2Y_1QD7cd0MYA==/109951170048506929.jpg",
"update_frequency": "每天更新",
"updated": "2025-08-27 01:24:43",
"updated_at": 1756257883349,
"created": "2014-06-30 07:58:56",
"created_at": 1404115136883,
"link": "https://music.163.com/#/discover/toplist?id=19723756"
},
{
"id": 3779629,
"name": "新歌榜",
"description": "云音乐新歌榜:云音乐用户一周内收听所有新歌(一月内最新发行) 官方TOP排行榜每天更新。",
"cover": "https://p1.music.126.net/5guhqPBTcIrrhLBotgaT6w==/109951170048511751.jpg",
"update_frequency": "每天更新",
"updated": "2025-08-27 00:56:52",
"updated_at": 1756256212440,
"created": "2013-09-09 10:09:58",
"created_at": 1378721398225,
"link": "https://music.163.com/#/discover/toplist?id=3779629"
},
{
"id": 2884035,
"name": "原创榜",
"description": "云音乐独立原创音乐人作品官方榜单以推荐优秀原创作品为目的。每周四网易云音乐首发。申请网易音乐人http://music.163.com/nmusician/",
"cover": "https://p1.music.126.net/BaP9nrocNTL3gGThysv4eQ==/109951170091896587.jpg",
"update_frequency": "每周四更新",
"updated": "2025-08-21 02:53:19",
"updated_at": 1755744799157,
"created": "2013-07-25 06:05:25",
"created_at": 1374732325894,
"link": "https://music.163.com/#/discover/toplist?id=2884035"
},
{
"id": 3778678,
"name": "热歌榜",
"description": "云音乐热歌榜云音乐用户一周内收听所有线上歌曲官方TOP排行榜每日更新。",
"cover": "https://p1.music.126.net/0SUEG8yDACfx0Bw2MYFv4Q==/109951170048519512.jpg",
"update_frequency": "每天更新",
"updated": "2025-08-27 00:57:07",
"updated_at": 1756256227510,
"created": "2013-09-09 10:10:06",
"created_at": 1378721406014,
"link": "https://music.163.com/#/discover/toplist?id=3778678"
},
{
"id": 991319590,
"name": "网易云中文说唱榜",
"description": "网易云原创说唱音乐人作品官方榜单每周五更新。以网易云用户一周播放热度为主收录2个月内发行的原创说唱作品按照综合数据排名取前50名。申请网易音乐人http://music.163.com/nmusician",
"cover": "https://p1.music.126.net/GgHbgDfGXHpE2YTchU7IvA==/109951171510498108.jpg",
"update_frequency": "每周五更新",
"updated": "2025-08-22 02:45:48",
"updated_at": 1755830748504,
"created": "2017-11-10 05:06:29",
"created_at": 1510290389440,
"link": "https://music.163.com/#/discover/toplist?id=991319590"
},
{
"id": 71384707,
"name": "网易云古典榜",
"description": "网易云用户一周内收听所有古典音乐官方TOP排行榜每周四更新。",
"cover": "https://p1.music.126.net/urByD_AmfBDBrs7fA9-O8A==/109951167976973225.jpg",
"update_frequency": "每周四更新",
"updated": "2025-08-21 02:59:09",
"updated_at": 1755745149157,
"created": "2015-05-07 03:22:00",
"created_at": 1430968920537,
"link": "https://music.163.com/#/discover/toplist?id=71384707"
},
{
"id": 1978921795,
"name": "网易云电音榜",
"description": "网易云用户一周内收听电子音乐官方TOP排行榜每周五更新。喜力星电音用先锋电音带你解锁全新维度和体验",
"cover": "https://p1.music.126.net/hXGObvXfsGtFjFvRhOYAkA==/109951170091888741.jpg",
"update_frequency": "每周五更新",
"updated": "2025-08-22 09:07:49",
"updated_at": 1755853669156,
"created": "2017-11-16 09:47:12",
"created_at": 1510825632233,
"link": "https://music.163.com/#/discover/toplist?id=1978921795"
},
{
"id": 14028249541,
"name": "网易云全球说唱榜",
"description": "想聆听世界的说唱节奏?全球说唱榜每周五更新,聚焦华语地区以外的优秀说唱作品。根据云音乐用户每周播放热度数据,按照综合数据排名取前 50 名。",
"cover": "https://p1.music.126.net/0hhFjP6WyIjHYDXKW5E7BA==/109951171535150782.jpg",
"update_frequency": "每周五更新",
"updated": "2025-08-22 01:58:14",
"updated_at": 1755827894399,
"created": "2025-07-24 06:09:26",
"created_at": 1753337366883,
"link": "https://music.163.com/#/discover/toplist?id=14028249541"
},
{
"id": 13372522766,
"name": "潮流风向榜",
"description": "精心挑选云音乐极具声量的音乐作品,呈现歌曲真实热度趋势,榜单每日更新。",
"cover": "https://p1.music.126.net/dIKA5e7jCncz2Br1Toxgaw==/109951170621574552.jpg",
"update_frequency": "更新74首",
"updated": "2025-08-27 04:05:55",
"updated_at": 1756267555368,
"created": "2025-02-26 06:01:33",
"created_at": 1740549693794,
"link": "https://music.163.com/#/discover/toplist?id=13372522766"
},
{
"id": 12911403728,
"name": "音乐合伙人推荐榜",
"description": "音乐合伙人近一个月内推荐过的歌曲官方TOP排行榜每周一更新。 跟随音乐合伙人的步伐,一起发现那些隐藏的音乐瑰宝。",
"cover": "https://p1.music.126.net/s6ITpmGjKbyDpi7DPkqd2w==/109951170187827373.jpg",
"update_frequency": "每周一更新",
"updated": "2025-08-25 04:06:02",
"updated_at": 1756094762192,
"created": "2024-11-25 07:14:30",
"created_at": 1732518870190,
"link": "https://music.163.com/#/discover/toplist?id=12911403728"
},
{
"id": 12911589513,
"name": "音乐合伙人热歌榜",
"description": "音乐合伙人近一周评定过的高分热歌官方TOP排行榜每周一更新。 跟随音乐合伙人的步伐,一起发现那些隐藏的音乐瑰宝。",
"cover": "https://p1.music.126.net/RgYxQmB-ZUjkMRo2N1jWnQ==/109951170187823494.jpg",
"update_frequency": "每周一更新",
"updated": "2025-08-25 04:05:58",
"updated_at": 1756094758751,
"created": "2024-11-25 07:13:46",
"created_at": 1732518826543,
"link": "https://music.163.com/#/discover/toplist?id=12911589513"
},
{
"id": 12911619970,
"name": "音乐合伙人留名榜",
"description": "音乐合伙人近一个月内留名过的所有歌曲官方TOP排行榜每周一更新。 跟随音乐合伙人的步伐,一起发现那些隐藏的音乐瑰宝。",
"cover": "https://p1.music.126.net/aJJzGIxhkVaD7dX0XBNUnw==/109951170187831145.jpg",
"update_frequency": "每周一更新",
"updated": "2025-08-25 04:05:45",
"updated_at": 1756094745722,
"created": "2024-11-25 07:12:50",
"created_at": 1732518770868,
"link": "https://music.163.com/#/discover/toplist?id=12911619970"
},
{
"id": 12911379734,
"name": "音乐合伙人高分新歌榜",
"description": "音乐合伙人近期评定过的所有新歌一个月内最新发行官方TOP排行榜每周一更新。 跟随音乐合伙人的步伐,一起发现那些隐藏的音乐瑰宝。",
"cover": "https://p1.music.126.net/bfk15bvanhdPFU7yjPFgWA==/109951170187832038.jpg",
"update_frequency": "每周一更新",
"updated": "2025-08-25 04:05:50",
"updated_at": 1756094750117,
"created": "2024-11-25 07:11:53",
"created_at": 1732518713161,
"link": "https://music.163.com/#/discover/toplist?id=12911379734"
},
{
"id": 12768855486,
"name": "音乐合伙人高分榜",
"description": "音乐合伙人的高分歌曲官方榜单收录近半年来获得音乐合伙人高分推荐的TOP100首歌曲每日更新。跟随音乐合伙人的步伐一起发现那些隐藏的音乐瑰宝。",
"cover": "https://p1.music.126.net/fPP5T0Z8Ac15qNvRTcHa6g==/109951170074028970.jpg",
"update_frequency": "更新27首",
"updated": "2025-08-27 04:05:47",
"updated_at": 1756267547739,
"created": "2024-10-25 03:51:10",
"created_at": 1729828270342,
"link": "https://music.163.com/#/discover/toplist?id=12768855486"
},
{
"id": 5453912201,
"name": "黑胶VIP爱听榜",
"description": "云音乐站内会员播放热度TOP100的歌曲每周四更新。\n黑胶们都爱听什么歌曲\n热门好歌一站式收听让你念念不忘~\n做尊贵黑胶畅听品味好歌~",
"cover": "https://p1.music.126.net/qo6-o9n5AhMjNyejev38-A==/109951169743111905.jpg",
"update_frequency": "每周四更新",
"updated": "2025-08-21 10:05:01",
"updated_at": 1755770701110,
"created": "2021-01-08 06:30:24",
"created_at": 1610087424470,
"link": "https://music.163.com/#/discover/toplist?id=5453912201"
},
{
"id": 71385702,
"name": "网易云ACG榜",
"description": "网易云用户一周内收听所有ACG音乐官方TOP排行榜每周四更新。",
"cover": "https://p1.music.126.net/na1kEeCS1iZEkzOrs9r_9g==/109951167976973667.jpg",
"update_frequency": "每周四更新",
"updated": "2025-08-21 04:05:02",
"updated_at": 1755749102516,
"created": "2015-05-07 03:22:15",
"created_at": 1430968935040,
"link": "https://music.163.com/#/discover/toplist?id=71385702"
},
{
"id": 745956260,
"name": "网易云韩语榜",
"description": "网易云用户一周内收听所有韩语歌曲官方TOP排行榜每周四更新。",
"cover": "https://p1.music.126.net/5oN9YaFznwNGXkmi8i2Ytw==/109951167430864741.jpg",
"update_frequency": "每周四更新",
"updated": "2025-08-21 04:05:01",
"updated_at": 1755749101352,
"created": "2017-05-31 03:34:51",
"created_at": 1496201691281,
"link": "https://music.163.com/#/discover/toplist?id=745956260"
},
{
"id": 180106,
"name": "UK排行榜周榜",
"description": "UK排行榜",
"cover": "https://p1.music.126.net/fhAqiflLy3eU-ldmBQByrg==/109951165613082765.jpg",
"update_frequency": "每天更新",
"updated": "2025-08-25 03:59:06",
"updated_at": 1756094346206,
"created": "2013-02-19 02:09:26",
"created_at": 1361239766844,
"link": "https://music.163.com/#/discover/toplist?id=180106"
},
{
"id": 60198,
"name": "美国Billboard榜",
"description": "美国Billboard排行榜",
"cover": "https://p1.music.126.net/rwRsVIJHQ68gglhA6TNEYA==/109951165611413732.jpg",
"update_frequency": "刚刚更新",
"updated": "2025-08-27 03:38:38",
"updated_at": 1756265918370,
"created": "2013-01-22 02:51:16",
"created_at": 1358823076818,
"link": "https://music.163.com/#/discover/toplist?id=60198"
},
{
"id": 3812895,
"name": "Beatport全球电子舞曲榜",
"description": "Beatport全球电子舞曲排行榜TOP100本榜每周三更新",
"cover": "https://p1.music.126.net/oT-RHuPBJiD7WMoU7WG5Rw==/109951166093489621.jpg",
"update_frequency": "更新20首",
"updated": "2025-08-27 02:29:37",
"updated_at": 1756261777726,
"created": "2013-09-11 08:03:09",
"created_at": 1378886589466,
"link": "https://music.163.com/#/discover/toplist?id=3812895"
},
{
"id": 21845217,
"name": "KTV唛榜",
"description": "KTV唛榜是目前国内首个以全国超过200家KTV点歌平台真实数据的当红歌曲榜单。所涉及的KTV店铺覆盖全国近100多个城市囊括一、二、三线各级城市及地区。在综合全国各地KTV点唱数据的前提下进行汇总与统计。为了保证信息的及时性唛榜每周五更新。提供给K迷们最新和最准确的数据。",
"cover": "https://p1.music.126.net/5wDP78s43ydVTKt62C8OjQ==/109951165613100063.jpg",
"update_frequency": "每周五更新",
"updated": "2021-11-26 09:56:43",
"updated_at": 1637920603975,
"created": "2014-07-18 03:11:33",
"created_at": 1405653093230,
"link": "https://music.163.com/#/discover/toplist?id=21845217"
},
{
"id": 60131,
"name": "日本Oricon榜",
"description": "日本Oricon数字单曲周榜每周三更新欢迎关注。",
"cover": "https://p1.music.126.net/aXUPgImt8hhf4cMUZEjP4g==/109951165611417794.jpg",
"update_frequency": "每天更新",
"updated": "2025-08-22 02:15:24",
"updated_at": 1755828924438,
"created": "2013-01-08 08:51:24",
"created_at": 1357635084874,
"link": "https://music.163.com/#/discover/toplist?id=60131"
},
{
"id": 2809513713,
"name": "网易云欧美热歌榜",
"description": "网易云用户一周内收听所有欧美歌曲官方TOP排行榜每周四更新。\nWestern Hit Chart (updated every Thursday)",
"cover": "https://p1.music.126.net/70_EO_Dc7NT_hhfvsapzcQ==/109951167430862162.jpg",
"update_frequency": "每周四更新",
"updated": "2025-08-21 15:44:14",
"updated_at": 1755791054932,
"created": "2019-05-22 02:49:33",
"created_at": 1558493373769,
"link": "https://music.163.com/#/discover/toplist?id=2809513713"
},
{
"id": 2809577409,
"name": "网易云欧美新歌榜",
"description": "网易云用户一周内收听所有欧美新歌一月内最新发行官方TOP排行榜每天更新。\nWestern New Release Chart (new songs released in last 30 days, updated daily)\n",
"cover": "https://p1.music.126.net/0lPWpI9Ejn1OiW2LSbg-qw==/109951167430863224.jpg",
"update_frequency": "更新17首",
"updated": "2025-08-27 07:16:02",
"updated_at": 1756278962152,
"created": "2019-05-22 02:46:54",
"created_at": 1558493214795,
"link": "https://music.163.com/#/discover/toplist?id=2809577409"
},
{
"id": 27135204,
"name": "法国 NRJ Vos Hits 周榜",
"description": "法国NRJ电台national Radio de Jeunes成立于1981年总部位于法国巴黎。是法国最受欢迎的音乐电台和听众最多的广播电台之一。NRJ音乐奖素有法国的“格莱美”之称。此榜单针对NRJ电台法国本土热门歌曲排行。【每周五更新】",
"cover": "https://p1.music.126.net/-fyzrPWd06FfWl_0JDAxMQ==/109951165613108584.jpg",
"update_frequency": "每周五更新",
"updated": "2025-08-22 02:15:42",
"updated_at": 1755828942531,
"created": "2014-09-04 10:03:33",
"created_at": 1409825013948,
"link": "https://music.163.com/#/discover/toplist?id=27135204"
},
{
"id": 3001835560,
"name": "网易云ACG动画榜",
"description": "网易云中每天热度上升最快的100首ACG动画单曲每日更新。",
"cover": "https://p1.music.126.net/SkGlKQ6acixthb77VlD9eQ==/109951164432300406.jpg",
"update_frequency": "更新84首",
"updated": "2025-08-27 04:05:09",
"updated_at": 1756267509031,
"created": "2019-09-27 02:03:58",
"created_at": 1569549838610,
"link": "https://music.163.com/#/discover/toplist?id=3001835560"
},
{
"id": 3001795926,
"name": "网易云ACG游戏榜",
"description": "网易云中每天热度上升最快的100首ACG游戏单曲每日更新。",
"cover": "https://p1.music.126.net/hivOOHMwEmnn9s_6rgZwEQ==/109951164432303700.jpg",
"update_frequency": "更新87首",
"updated": "2025-08-27 04:05:18",
"updated_at": 1756267518248,
"created": "2019-09-27 02:04:56",
"created_at": 1569549896656,
"link": "https://music.163.com/#/discover/toplist?id=3001795926"
},
{
"id": 3001890046,
"name": "网易云ACG VOCALOID榜",
"description": "",
"cover": "https://p1.music.126.net/Ag7RyRCYiINcd9EtRXf6xA==/109951164432303690.jpg",
"update_frequency": "更新87首",
"updated": "2025-08-27 04:05:27",
"updated_at": 1756267527413,
"created": "2019-09-27 02:05:25",
"created_at": 1569549925472,
"link": "https://music.163.com/#/discover/toplist?id=3001890046"
},
{
"id": 5059644681,
"name": "网易云日语榜",
"description": "网易云用户一周内收听所有日语歌曲官方TOP排行榜每周二更新。",
"cover": "https://p1.music.126.net/YFBFNI2F-4BveUpv6FKFuw==/109951167430864069.jpg",
"update_frequency": "每周二更新",
"updated": "2025-08-26 06:05:02",
"updated_at": 1756188302867,
"created": "2020-06-11 08:10:00",
"created_at": 1591863000459,
"link": "https://music.163.com/#/discover/toplist?id=5059644681"
},
{
"id": 5059633707,
"name": "网易云摇滚榜",
"description": "网易云用户一周内收听所有摇滚歌曲官方TOP排行榜每周五更新。",
"cover": "https://p1.music.126.net/LjkX2hktgFD1NXc3W6w0sA==/109951170048522513.jpg",
"update_frequency": "每周五更新",
"updated": "2025-08-22 09:12:43",
"updated_at": 1755853963904,
"created": "2020-06-11 08:13:33",
"created_at": 1591863213389,
"link": "https://music.163.com/#/discover/toplist?id=5059633707"
},
{
"id": 5059642708,
"name": "网易云国风榜",
"description": "网易云用户一周内收听所有国风歌曲官方TOP排行榜每周五更新。",
"cover": "https://p1.music.126.net/kTJC5OBhg8I477X_ZmXyDQ==/109951168539740982.jpg",
"update_frequency": "每周五更新",
"updated": "2025-08-22 03:10:57",
"updated_at": 1755832257607,
"created": "2020-06-11 08:14:18",
"created_at": 1591863258438,
"link": "https://music.163.com/#/discover/toplist?id=5059642708"
},
{
"id": 5338990334,
"name": "潜力爆款榜",
"description": "全民一起PICK潜力好歌每周二更新",
"cover": "https://p1.music.126.net/Mi4QPklg1mtbWAfq74tEqQ==/109951165498334721.jpg",
"update_frequency": "每周二更新",
"updated": "2025-08-26 04:05:32",
"updated_at": 1756181132964,
"created": "2020-11-17 06:24:34",
"created_at": 1605594274077,
"link": "https://music.163.com/#/discover/toplist?id=5338990334"
},
{
"id": 5059661515,
"name": "网易云民谣榜",
"description": "网易云用户一周内收听所有民谣歌曲官方TOP排行榜每周五更新。",
"cover": "https://p1.music.126.net/Xe9qLTAqtBAWX_hPgFHMyw==/109951170048510929.jpg",
"update_frequency": "每周五更新",
"updated": "2025-08-22 08:39:36",
"updated_at": 1755851976839,
"created": "2020-06-11 08:10:52",
"created_at": 1591863052757,
"link": "https://music.163.com/#/discover/toplist?id=5059661515"
},
{
"id": 6688069460,
"name": "听歌识曲榜",
"description": "网易云音乐站内歌曲按用户“听歌识曲”次数排列,每周四更新",
"cover": "https://p1.music.126.net/wJVUAiUuykKk7yGbQxDBug==/109951167430857712.jpg",
"update_frequency": "每周四更新",
"updated": "2025-08-21 15:35:02",
"updated_at": 1755790502462,
"created": "2021-03-31 08:45:54",
"created_at": 1617180354803,
"link": "https://music.163.com/#/discover/toplist?id=6688069460"
},
{
"id": 6723173524,
"name": "网络热歌榜",
"description": "网罗一周热门网络歌曲,反映云音乐用户近一周网络热歌收听趋势。每周五更新。",
"cover": "https://p1.music.126.net/_kSxOPqQ5J5etC5DKTFwNA==/109951170048519530.jpg",
"update_frequency": "每周五更新",
"updated": "2025-08-22 01:59:18",
"updated_at": 1755827958008,
"created": "2021-04-22 02:41:46",
"created_at": 1619059306654,
"link": "https://music.163.com/#/discover/toplist?id=6723173524"
},
{
"id": 6732051320,
"name": "俄语榜",
"description": "网易云音乐用户一周内收听所有俄罗斯语歌曲官方TOP排行榜每周四更新。",
"cover": "https://p1.music.126.net/HbJ0BK5doY4I4pEMY6-FQw==/109951167430852698.jpg",
"update_frequency": "每周四更新",
"updated": "2025-08-21 04:05:27",
"updated_at": 1755749127585,
"created": "2021-04-28 04:05:12",
"created_at": 1619582712108,
"link": "https://music.163.com/#/discover/toplist?id=6732051320"
},
{
"id": 6732014811,
"name": "越南语榜",
"description": "网易云音乐用户一周内收听所有越南语歌曲官方TOP排行榜每周四更新。",
"cover": "https://p1.music.126.net/N-Y5maLGWgrowt3TE6RtSg==/109951167430857045.jpg",
"update_frequency": "每周四更新",
"updated": "2025-08-21 04:05:28",
"updated_at": 1755749128002,
"created": "2021-04-28 04:05:49",
"created_at": 1619582749349,
"link": "https://music.163.com/#/discover/toplist?id=6732014811"
},
{
"id": 6886768100,
"name": "中文慢摇DJ榜",
"description": "搜索“DJ”进入慢摇DJ专区探索更多网络热歌",
"cover": "https://p1.music.126.net/w_01BfDU012ojxnzLO6tYw==/109951167977358686.jpg",
"update_frequency": "刚刚更新",
"updated": "2025-08-27 04:00:00",
"updated_at": 1756267200565,
"created": "2021-07-28 10:09:59",
"created_at": 1627466999260,
"link": "https://music.163.com/#/discover/toplist?id=6886768100"
},
{
"id": 6939992364,
"name": "俄罗斯top hit流行音乐榜",
"description": "top hit榜根据俄罗斯及全球400多个无线广播的音乐播放量和YouTube播放量计算得来每周一更新。",
"cover": "https://p1.music.126.net/KLVO8PxVZzOoLdWQQNyprA==/109951166327316568.jpg",
"update_frequency": "每周五更新",
"updated": "2025-08-22 06:10:23",
"updated_at": 1755843023964,
"created": "2021-08-27 03:30:02",
"created_at": 1630035002268,
"link": "https://music.163.com/#/discover/toplist?id=6939992364"
},
{
"id": 7095271308,
"name": "泰语榜",
"description": "网易云音乐用户一周内收听所有泰语歌曲官方TOP排行榜每周四更新。",
"cover": "https://p1.music.126.net/4W0WBHBgwYlYfRniuyL47A==/109951167430843284.jpg",
"update_frequency": "每周四更新",
"updated": "2025-08-21 02:26:07",
"updated_at": 1755743167588,
"created": "2021-11-29 06:22:17",
"created_at": 1638166937809,
"link": "https://music.163.com/#/discover/toplist?id=7095271308"
},
{
"id": 7356827205,
"name": "BEAT排行榜",
"description": "嘿~朋友欢迎来到本周的Beat排行榜\n我们挑选了近一周内热门的Beat作品一起来感受下大家近期的“口味”吧\n每周都会更新哦记得按下收藏我每天都会在这里等你来与我交流~\n\n关于Beat的必备小知识\nQ1.什么是Beat\nBeat即节拍特指嘻哈音乐中的伴奏现在也可指所有流行音乐的伴奏\nQ2.Beat有什么用\n在Beat的帮助下你只需要填词演唱即可完成一首歌曲的创作而且Beat也可以作为各种流媒体的背景音乐或是多场景现场演出的得力助手不同风格的Beat还能为你的音乐创作提供灵感哦~\n搜索关注“BEATSOUL激灵”网易云官号探索更多炸裂音乐内容",
"cover": "https://p1.music.126.net/yhzlQJCJ9NcT4MvJBG_HgQ==/109951167977014958.jpg",
"update_frequency": "每周四更新",
"updated": "2025-08-21 12:05:01",
"updated_at": 1755777901037,
"created": "2022-03-29 11:39:58",
"created_at": 1648553998273,
"link": "https://music.163.com/#/discover/toplist?id=7356827205"
},
{
"id": 7325478166,
"name": "星云榜VOL.29 Addison Rae新专来袭寻找最真实的自己",
"description": "精心评审,专业推荐。每周五更新,为你呈现宝藏新歌。\n1、《Aquamarinee》歌手Addison Rae\n2、《羽毛剑》歌手秦凡淇\n3、《Take me back》歌手HAIM\n4、《妈妈的眼睛》歌手张震岳\n5、《25岁永不停下》歌手张醒婵\n6、《雨季症候》歌手SHARK卫彬月\n7、《山东王FREESTYLE》歌手华云龙KLE\n8、《LOVE I NEED》歌手陈瑜Estelle\n9、《FFFFF》歌手刘柏辛Lexie\n10、《Vipaśyanā》歌手Namunong\n本期封面Addison RaeAquamarine",
"cover": "https://p2.music.126.net/u440jFG0N5i06C9ejOeMCQ==/109951171381091309.jpg",
"update_frequency": "每周五更新",
"updated": "2025-06-30 08:17:26",
"updated_at": 1751271446032,
"created": "2022-03-09 03:24:46",
"created_at": 1646796286440,
"link": "https://music.163.com/#/discover/toplist?id=7325478166"
},
{
"id": 7603212484,
"name": "LOOK直播歌曲榜",
"description": "LOOK直播好歌共赏专属你的声音聊愈场。榜单选取符合条件且近7日热度最高的前50首歌曲每周二更新。",
"cover": "https://p2.music.126.net/u-RQC-LyY0aoeseRumJ14A==/109951167977730469.jpg",
"update_frequency": "每周二更新",
"updated": "2024-05-07 13:23:03",
"updated_at": 1715088183913,
"created": "2022-08-23 01:54:56",
"created_at": 1661219696017,
"link": "https://music.163.com/#/discover/toplist?id=7603212484"
},
{
"id": 7775163417,
"name": "赏音榜",
"description": "云音乐歌曲赏音榜以让用户鉴赏到更多潜力好歌为目的以用户对歌曲互动热度为核心按照综合数据排名取前100名每日更新",
"cover": "https://p2.music.126.net/m9hQzC-d5wefBipedNPaHg==/109951168178601971.jpg",
"update_frequency": "更新92首",
"updated": "2025-08-27 04:05:36",
"updated_at": 1756267536926,
"created": "2022-11-28 06:46:19",
"created_at": 1669617979380,
"link": "https://music.163.com/#/discover/toplist?id=7775163417"
},
{
"id": 7785123708,
"name": "黑胶VIP新歌榜",
"description": "云音乐站内播放热度TOP50的7日内新晋会员歌曲每日更新。\n更适合黑胶体质的新歌榜单来啦\n耳机分你一只新曲一起来听~\n成为尊贵黑胶不错过每一首VIP新歌",
"cover": "https://p2.music.126.net/vjitpkT9nXBCth6tvdDMWg==/109951169743115266.jpg",
"update_frequency": "更新33首",
"updated": "2025-08-27 04:05:38",
"updated_at": 1756267538662,
"created": "2022-12-02 10:51:16",
"created_at": 1669978276103,
"link": "https://music.163.com/#/discover/toplist?id=7785123708"
},
{
"id": 7785066739,
"name": "黑胶VIP热歌榜",
"description": "云音乐站内播放和付费热度TOP50的会员歌曲每日更新。\n更适合黑胶体质的热歌榜单来啦\n哪首是你的单曲循环\n成为尊贵黑胶随心畅听热门好歌",
"cover": "https://p2.music.126.net/Ay3mLgQ9weG_c8JjYrD-Bw==/109951169743106495.jpg",
"update_frequency": "刚刚更新",
"updated": "2025-08-27 04:05:37",
"updated_at": 1756267537688,
"created": "2022-12-02 10:51:31",
"created_at": 1669978291024,
"link": "https://music.163.com/#/discover/toplist?id=7785066739"
},
{
"id": 7785091694,
"name": "黑胶VIP爱搜榜",
"description": "云音乐站内会员搜索播放热度TOP50的歌曲每日更新。\n更适合黑胶体质的搜歌榜单来啦\n热搜好歌一网打尽只为有品位的你~\n成为尊贵黑胶你搜我听畅听不停",
"cover": "https://p2.music.126.net/R7DtZqNraesnsiaIKvzTHA==/109951169743112799.jpg",
"update_frequency": "更新36首",
"updated": "2025-08-27 04:05:42",
"updated_at": 1756267542318,
"created": "2022-12-02 10:51:43",
"created_at": 1669978303210,
"link": "https://music.163.com/#/discover/toplist?id=7785091694"
},
{
"id": 8246775932,
"name": "实时热度榜",
"description": "每天9-23点为你精选当下歌曲热度最高的歌曲",
"cover": "https://p2.music.126.net/U7ZbdpWzRdmZVr6Khn_4ag==/109951168673982478.jpg",
"update_frequency": "刚刚更新",
"updated": "2025-08-27 13:15:01",
"updated_at": 1756300501119,
"created": "2023-03-20 02:39:59",
"created_at": 1679279999154,
"link": "https://music.163.com/#/discover/toplist?id=8246775932"
},
{
"id": 8537588450,
"name": "喜力®星电音派对潮音榜",
"description": "乐无界,越未来!《星电音联盟》歌曲官方榜单,每周一更新,让云村村民们随时随地躁起高燃派对氛围!喜力®星电音构建狂欢永不停歇的新奇电音宇宙,激活潮流基因,释放先锋灵感,跨维开启奇妙电音之旅!",
"cover": "https://p2.music.126.net/HVu2hGYvzN5XBuvFc_4Bgg==/109951168730309120.jpg",
"update_frequency": "每周五更新",
"updated": "2024-09-16 04:05:30",
"updated_at": 1726459530378,
"created": "2023-07-07 02:48:39",
"created_at": 1688698119437,
"link": "https://music.163.com/#/discover/toplist?id=8537588450"
},
{
"id": 8661209031,
"name": "乐夏榜",
"description": "听乐夏,上网易云,一头扎进爱音乐的人群! 综艺《乐队的夏天3》官方榜单每周一更新。和三星折叠屏手机一起畅听《乐队的夏天3》官方榜单折叠看三星五代更来劲。",
"cover": "https://p2.music.126.net/RlStCmE97y0xYFk7rS3Zww==/109951168864907822.jpg",
"update_frequency": "每周一更新",
"updated": "2025-08-25 04:05:40",
"updated_at": 1756094740529,
"created": "2023-08-16 09:47:27",
"created_at": 1692179247425,
"link": "https://music.163.com/#/discover/toplist?id=8661209031"
},
{
"id": 8703179781,
"name": "特斯拉车友爱听榜",
"description": null,
"cover": "https://p2.music.126.net/UL8dhobSa3TR6Wd1JmWe_g==/109951168924385363.jpg",
"update_frequency": "每周一更新",
"updated": "2025-08-25 08:05:04",
"updated_at": 1756109104224,
"created": "2023-08-31 04:29:59",
"created_at": 1693456199735,
"link": "https://music.163.com/#/discover/toplist?id=8703179781"
},
{
"id": 8703052295,
"name": "理想车友爱听榜",
"description": null,
"cover": "https://p2.music.126.net/U--PWdWupY1ER5cVSjr1jQ==/109951168928365496.jpg",
"update_frequency": "每周一更新",
"updated": "2025-08-25 08:05:04",
"updated_at": 1756109104985,
"created": "2023-08-31 04:38:29",
"created_at": 1693456709598,
"link": "https://music.163.com/#/discover/toplist?id=8703052295"
},
{
"id": 8702582160,
"name": "比亚迪车友爱听榜",
"description": null,
"cover": "https://p2.music.126.net/S1OG-OLTaofa3HfrHW48kA==/109951168924393585.jpg",
"update_frequency": "每周一更新",
"updated": "2025-08-25 08:05:03",
"updated_at": 1756109103855,
"created": "2023-08-31 04:38:42",
"created_at": 1693456722262,
"link": "https://music.163.com/#/discover/toplist?id=8702582160"
},
{
"id": 8703220480,
"name": "蔚来车友爱听榜",
"description": null,
"cover": "https://p2.music.126.net/r9kBQNsOro1EAB82Ol51WQ==/109951168924380971.jpg",
"update_frequency": "每周一更新",
"updated": "2025-08-25 08:05:02",
"updated_at": 1756109102267,
"created": "2023-08-31 04:38:56",
"created_at": 1693456736086,
"link": "https://music.163.com/#/discover/toplist?id=8703220480"
},
{
"id": 8702982391,
"name": "极氪车友爱听榜",
"description": null,
"cover": "https://p2.music.126.net/Cu0RXoKewSPM9Gyc7Cp8jw==/109951168924391596.jpg",
"update_frequency": "每周一更新",
"updated": "2025-08-25 08:05:03",
"updated_at": 1756109103634,
"created": "2023-08-31 04:39:19",
"created_at": 1693456759762,
"link": "https://music.163.com/#/discover/toplist?id=8702982391"
},
{
"id": 8532443277,
"name": "蛋仔派对听歌榜",
"description": "来自蛋仔岛的热播歌曲速递,网易《蛋仔派对》官方榜单,每周五更新。云村村民们,和蛋仔们一起随歌摇摆吧!",
"cover": "https://p2.music.126.net/TMb0be5QLMZKOFeuOKT4tg==/109951168717283910.jpg",
"update_frequency": "每周五更新",
"updated": "2025-08-22 04:05:44",
"updated_at": 1755835544365,
"created": "2023-07-05 02:32:04",
"created_at": 1688524324879,
"link": "https://music.163.com/#/discover/toplist?id=8532443277"
},
{
"id": 9651277674,
"name": "AI歌曲榜",
"description": "精心挑选每日最新最热AI生成歌曲榜单每日更新一起感受AI的独特魅力吧",
"cover": "https://p2.music.126.net/M0m6GeZ1Y8Osz9jqxaW8Wg==/109951169462048035.jpg",
"update_frequency": "更新12首",
"updated": "2025-08-27 04:05:43",
"updated_at": 1756267543655,
"created": "2024-04-02 10:25:12",
"created_at": 1712053512213,
"link": "https://music.163.com/#/discover/toplist?id=9651277674"
},
{
"id": 10131772880,
"name": "昊铂车友爱听榜",
"description": null,
"cover": "https://p2.music.126.net/EL7H4rkKejZY7Uv54EFNXg==/109951169655010112.jpg",
"update_frequency": "每周一更新",
"updated": "2025-08-25 08:05:01",
"updated_at": 1756109101438,
"created": "2024-06-04 08:50:00",
"created_at": 1717491000945,
"link": "https://music.163.com/#/discover/toplist?id=10131772880"
},
{
"id": 10162841534,
"name": "埃安车友爱听榜",
"description": "埃安车友平时都在听什么??",
"cover": "https://p2.music.126.net/FcP1U6Bck0wPKqd0XgBwSQ==/109951169679731241.jpg",
"update_frequency": "每周一更新",
"updated": "2025-08-25 08:05:03",
"updated_at": 1756109103115,
"created": "2024-06-12 05:31:44",
"created_at": 1718170304691,
"link": "https://music.163.com/#/discover/toplist?id=10162841534"
},
{
"id": 12225155968,
"name": "欧美R&B榜",
"description": "云音乐用户一周内收听节奏布鲁斯R&B官方TOP排行榜每周五更新。",
"cover": "https://p2.music.126.net/0E6MzYzyA5uvQ4CSoIG2mw==/109951169739660034.jpg",
"update_frequency": "每周五更新",
"updated": "2025-08-22 04:05:46",
"updated_at": 1755835546525,
"created": "2024-06-25 10:14:05",
"created_at": 1719310445382,
"link": "https://music.163.com/#/discover/toplist?id=12225155968"
},
{
"id": 12344472377,
"name": "黑胶VIP限免榜",
"description": "云音乐站内热度最高的限免播放歌曲TOP50每日更新。\n人气旋律一听就会爱上现在马上进入免费模式点击云音乐首页左上角侧边栏选择“免费听歌”畅听全榜吧",
"cover": "https://p2.music.126.net/WXCSf4ZNcDCdOTY5ixm3Bg==/109951169809318325.jpg",
"update_frequency": "更新11首",
"updated": "2025-08-27 04:05:44",
"updated_at": 1756267544856,
"created": "2024-07-23 08:08:37",
"created_at": 1721722117311,
"link": "https://music.163.com/#/discover/toplist?id=12344472377"
},
{
"id": 12717025277,
"name": "吉利车友爱听榜",
"description": null,
"cover": "https://p2.music.126.net/XVmZb3JSyrwMgqu9WVz61A==/109951170037568570.jpg",
"update_frequency": "每周一更新",
"updated": "2025-08-25 08:05:00",
"updated_at": 1756109100809,
"created": "2024-10-12 05:44:04",
"created_at": 1728711844151,
"link": "https://music.163.com/#/discover/toplist?id=12717025277"
}
]
}

View File

@@ -1,123 +0,0 @@
/* 背景样式文件 */
body {
background: linear-gradient(135deg, #E8F5E8 0%, #F1F8E9 25%, #E0F2F1 50%, #E8F5E8 75%, #F3E5F5 100%);
background-size: 400% 400%;
animation: gradientShift 15s ease infinite;
position: relative;
}
/* 背景渐变动画 */
@keyframes gradientShift {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
/* 背景装饰元素 */
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image:
radial-gradient(circle at 20% 80%, rgba(76, 175, 80, 0.1) 0%, transparent 50%),
radial-gradient(circle at 80% 20%, rgba(129, 199, 132, 0.1) 0%, transparent 50%),
radial-gradient(circle at 40% 40%, rgba(165, 214, 167, 0.08) 0%, transparent 50%);
pointer-events: none;
z-index: -2;
}
/* 背景粒子效果 */
body::after {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image:
radial-gradient(2px 2px at 20px 30px, rgba(76, 175, 80, 0.3), transparent),
radial-gradient(2px 2px at 40px 70px, rgba(129, 199, 132, 0.2), transparent),
radial-gradient(1px 1px at 90px 40px, rgba(165, 214, 167, 0.3), transparent),
radial-gradient(1px 1px at 130px 80px, rgba(76, 175, 80, 0.2), transparent),
radial-gradient(2px 2px at 160px 30px, rgba(129, 199, 132, 0.3), transparent);
background-repeat: repeat;
background-size: 200px 100px;
animation: particleFloat 20s linear infinite;
pointer-events: none;
z-index: -1;
opacity: 0.6;
}
@keyframes particleFloat {
0% {
transform: translateY(0px);
}
100% {
transform: translateY(-100px);
}
}
/* 响应式背景调整 */
@media (max-width: 768px) {
body::after {
background-size: 150px 75px;
animation-duration: 25s;
}
}
@media (max-width: 480px) {
body::after {
background-size: 100px 50px;
animation-duration: 30s;
opacity: 0.4;
}
}
/* 高性能模式 - 减少动画 */
@media (prefers-reduced-motion: reduce) {
body {
animation: none;
background: linear-gradient(135deg, #E8F5E8 0%, #F1F8E9 50%, #E0F2F1 100%);
}
body::after {
animation: none;
}
.title {
animation: none;
}
}
/* 深色模式支持 */
@media (prefers-color-scheme: dark) {
body {
background: linear-gradient(135deg, #1B5E20 0%, #2E7D32 25%, #388E3C 50%, #43A047 75%, #4CAF50 100%);
}
body::before {
background-image:
radial-gradient(circle at 20% 80%, rgba(255, 255, 255, 0.05) 0%, transparent 50%),
radial-gradient(circle at 80% 20%, rgba(255, 255, 255, 0.03) 0%, transparent 50%),
radial-gradient(circle at 40% 40%, rgba(255, 255, 255, 0.02) 0%, transparent 50%);
}
body::after {
background-image:
radial-gradient(1px 1px at 20px 30px, rgba(255, 255, 255, 0.1), transparent),
radial-gradient(1px 1px at 40px 70px, rgba(255, 255, 255, 0.08), transparent),
radial-gradient(1px 1px at 90px 40px, rgba(255, 255, 255, 0.06), transparent),
radial-gradient(1px 1px at 130px 80px, rgba(255, 255, 255, 0.04), transparent),
radial-gradient(1px 1px at 160px 30px, rgba(255, 255, 255, 0.05), transparent);
opacity: 0.3;
}
}

View File

@@ -1,483 +0,0 @@
/* 基础样式重置 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Microsoft YaHei', 'PingFang SC', 'Helvetica Neue', Arial, sans-serif;
line-height: 1.6;
color: #2c3e50;
min-height: 100vh;
overflow-x: hidden;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
position: relative;
z-index: 1;
}
/* 头部样式 */
.header {
text-align: center;
margin-bottom: 40px;
padding: 40px 20px;
background: rgba(255, 255, 255, 0.9);
border-radius: 20px;
backdrop-filter: blur(10px);
box-shadow: 0 8px 32px rgba(76, 175, 80, 0.1);
}
.title {
font-size: 2.5rem;
font-weight: 700;
background: linear-gradient(135deg, #4CAF50, #81C784);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
margin-bottom: 10px;
animation: titleGlow 3s ease-in-out infinite alternate;
}
@keyframes titleGlow {
from { filter: drop-shadow(0 0 5px rgba(76, 175, 80, 0.3)); }
to { filter: drop-shadow(0 0 15px rgba(76, 175, 80, 0.6)); }
}
.subtitle {
font-size: 1.1rem;
color: #666;
opacity: 0.8;
}
/* 榜单信息样式 */
.rank-info {
background: rgba(255, 255, 255, 0.95);
border-radius: 15px;
padding: 25px;
margin-bottom: 30px;
box-shadow: 0 6px 25px rgba(76, 175, 80, 0.1);
border: 1px solid rgba(76, 175, 80, 0.2);
}
.rank-header {
display: flex;
gap: 20px;
align-items: flex-start;
}
.rank-cover {
width: 120px;
height: 120px;
border-radius: 12px;
object-fit: cover;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
flex-shrink: 0;
}
.rank-details {
flex: 1;
}
.rank-name {
font-size: 1.8rem;
color: #2c3e50;
margin-bottom: 10px;
font-weight: 600;
}
.rank-description {
color: #666;
margin-bottom: 15px;
line-height: 1.6;
}
.rank-meta {
display: flex;
gap: 20px;
flex-wrap: wrap;
}
.update-time, .update-frequency {
background: linear-gradient(135deg, #E8F5E8, #C8E6C9);
padding: 6px 12px;
border-radius: 20px;
font-size: 0.9rem;
color: #2E7D32;
border: 1px solid rgba(76, 175, 80, 0.3);
}
/* 控制区域样式 */
.controls {
background: rgba(255, 255, 255, 0.9);
border-radius: 15px;
padding: 25px;
margin-bottom: 30px;
box-shadow: 0 6px 25px rgba(76, 175, 80, 0.1);
}
.input-group {
display: flex;
gap: 15px;
align-items: center;
flex-wrap: wrap;
}
.input-group label {
font-weight: 600;
color: #2c3e50;
min-width: 80px;
}
#rankId {
flex: 1;
min-width: 200px;
padding: 12px 16px;
border: 2px solid #E0E0E0;
border-radius: 10px;
font-size: 1rem;
transition: all 0.3s ease;
background: rgba(255, 255, 255, 0.9);
}
#rankId:focus {
outline: none;
border-color: #4CAF50;
box-shadow: 0 0 0 3px rgba(76, 175, 80, 0.1);
}
.load-btn {
padding: 12px 24px;
background: linear-gradient(135deg, #4CAF50, #66BB6A);
color: white;
border: none;
border-radius: 10px;
font-size: 1rem;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 4px 15px rgba(76, 175, 80, 0.3);
}
.load-btn:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(76, 175, 80, 0.4);
}
.load-btn:active {
transform: translateY(0);
}
.load-btn:disabled {
opacity: 0.6;
cursor: not-allowed;
transform: none;
}
/* 加载动画 */
.loading {
text-align: center;
padding: 40px;
background: rgba(255, 255, 255, 0.9);
border-radius: 15px;
margin-bottom: 30px;
}
.spinner {
width: 40px;
height: 40px;
border: 4px solid #E0E0E0;
border-top: 4px solid #4CAF50;
border-radius: 50%;
animation: spin 1s linear infinite;
margin: 0 auto 15px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* 错误提示 */
.error {
text-align: center;
padding: 30px;
background: rgba(255, 245, 245, 0.95);
border: 2px solid #ffcdd2;
border-radius: 15px;
margin-bottom: 30px;
}
.error-icon {
font-size: 3rem;
margin-bottom: 15px;
}
.error-message {
color: #c62828;
margin-bottom: 20px;
font-size: 1.1rem;
}
.retry-btn {
padding: 10px 20px;
background: #f44336;
color: white;
border: none;
border-radius: 8px;
cursor: pointer;
transition: all 0.3s ease;
}
.retry-btn:hover {
background: #d32f2f;
transform: translateY(-1px);
}
/* 歌曲列表样式 */
.song-list {
background: rgba(255, 255, 255, 0.95);
border-radius: 15px;
padding: 25px;
margin-bottom: 30px;
box-shadow: 0 6px 25px rgba(76, 175, 80, 0.1);
}
.list-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 25px;
padding-bottom: 15px;
border-bottom: 2px solid #E8F5E8;
}
.list-header h3 {
font-size: 1.5rem;
color: #2c3e50;
font-weight: 600;
}
.song-count {
background: linear-gradient(135deg, #4CAF50, #66BB6A);
color: white;
padding: 6px 12px;
border-radius: 20px;
font-size: 0.9rem;
font-weight: 600;
}
/* 歌曲项样式 */
.song-item {
display: flex;
align-items: center;
padding: 15px;
margin-bottom: 12px;
background: rgba(248, 255, 248, 0.8);
border-radius: 12px;
transition: all 0.3s ease;
border: 1px solid rgba(76, 175, 80, 0.1);
cursor: pointer;
}
.song-item:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(76, 175, 80, 0.15);
background: rgba(232, 245, 232, 0.9);
}
.song-rank {
font-size: 1.2rem;
font-weight: 700;
color: #4CAF50;
min-width: 40px;
text-align: center;
}
.song-rank.top3 {
background: linear-gradient(135deg, #FFD700, #FFA000);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.song-info {
flex: 1;
margin-left: 15px;
}
.song-title {
font-size: 1.1rem;
font-weight: 600;
color: #2c3e50;
margin-bottom: 5px;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
overflow: hidden;
}
.song-artist {
color: #666;
font-size: 0.9rem;
margin-bottom: 3px;
}
.song-album {
color: #888;
font-size: 0.85rem;
}
.song-meta {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 5px;
}
.song-duration {
color: #666;
font-size: 0.9rem;
}
.song-popularity {
background: linear-gradient(135deg, #4CAF50, #66BB6A);
color: white;
padding: 3px 8px;
border-radius: 12px;
font-size: 0.8rem;
font-weight: 600;
}
/* 返回按钮 */
.back-to-list {
text-align: center;
margin: 30px 0;
}
.back-btn {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 12px 24px;
background: linear-gradient(135deg, #81C784, #A5D6A7);
color: white;
text-decoration: none;
border-radius: 10px;
font-weight: 600;
transition: all 0.3s ease;
box-shadow: 0 4px 15px rgba(129, 199, 132, 0.3);
}
.back-btn:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(129, 199, 132, 0.4);
}
/* 页脚 */
.footer {
text-align: center;
padding: 30px 20px;
background: rgba(255, 255, 255, 0.9);
border-radius: 15px;
margin-top: 40px;
color: #666;
backdrop-filter: blur(10px);
}
/* 响应式设计 */
@media (max-width: 768px) {
.container {
padding: 15px;
}
.title {
font-size: 2rem;
}
.rank-header {
flex-direction: column;
text-align: center;
}
.rank-cover {
width: 100px;
height: 100px;
margin: 0 auto 15px;
}
.input-group {
flex-direction: column;
align-items: stretch;
}
.input-group label {
min-width: auto;
margin-bottom: 5px;
}
#rankId {
min-width: auto;
margin-bottom: 10px;
}
.song-item {
flex-direction: column;
text-align: center;
gap: 10px;
}
.song-info {
margin-left: 0;
}
.song-meta {
align-items: center;
flex-direction: row;
justify-content: center;
}
.list-header {
flex-direction: column;
gap: 10px;
text-align: center;
}
}
@media (max-width: 480px) {
.title {
font-size: 1.8rem;
}
.header {
padding: 30px 15px;
}
.rank-info, .controls, .song-list {
padding: 20px;
}
.song-item {
padding: 12px;
}
}
/* 平板端适配 */
@media (min-width: 769px) and (max-width: 1024px) {
.container {
padding: 25px;
}
.song-item {
padding: 18px;
}
.rank-cover {
width: 110px;
height: 110px;
}
}

View File

@@ -1,69 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>网易云榜单详情</title>
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="css/background.css">
</head>
<body>
<div class="container">
<header class="header">
<h1 class="title">🎵 网易云榜单详情</h1>
<p class="subtitle">发现音乐的魅力</p>
</header>
<div class="rank-info" id="rankInfo" style="display: none;">
<div class="rank-header">
<img class="rank-cover" id="rankCover" src="" alt="榜单封面">
<div class="rank-details">
<h2 class="rank-name" id="rankName"></h2>
<p class="rank-description" id="rankDescription"></p>
<div class="rank-meta">
<span class="update-time" id="updateTime"></span>
<span class="update-frequency" id="updateFrequency"></span>
</div>
</div>
</div>
</div>
<div class="controls">
<div class="input-group">
<label for="rankId">榜单ID:</label>
<input type="text" id="rankId" placeholder="请输入榜单ID3778678">
<button id="loadBtn" class="load-btn">加载榜单</button>
</div>
</div>
<div class="loading" id="loading" style="display: none;">
<div class="spinner"></div>
<p>正在加载榜单数据...</p>
</div>
<div class="error" id="error" style="display: none;">
<div class="error-icon">⚠️</div>
<p class="error-message" id="errorMessage"></p>
<button class="retry-btn" id="retryBtn">重试</button>
</div>
<div class="song-list" id="songList" style="display: none;">
<div class="list-header">
<h3>歌曲列表</h3>
<div class="song-count" id="songCount"></div>
</div>
<div class="songs" id="songs"></div>
</div>
<div class="back-to-list">
<a href="../网易云榜单列表/index.html" class="back-btn">← 返回榜单列表</a>
</div>
</div>
<footer class="footer">
<p>&copy; 2025 网易云榜单详情 - 数据来源于官方API</p>
</footer>
<script src="js/script.js"></script>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show More