diff --git a/.gitignore b/.gitignore index 9d38183f..fbcf9fc0 100755 --- a/.gitignore +++ b/.gitignore @@ -1,211 +1,4 @@ -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[codz] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -share/python-wheels/ -*.egg-info/ -.installed.cfg -*.egg -MANIFEST - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.nox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -*.py.cover -.hypothesis/ -.pytest_cache/ -cover/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py -db.sqlite3 -db.sqlite3-journal - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -.pybuilder/ -target/ - -# Jupyter Notebook -.ipynb_checkpoints - -# IPython -profile_default/ -ipython_config.py - -# pyenv -# For a library or package, you might want to ignore these files since the code is -# intended to run in multiple environments; otherwise, check them in: -# .python-version - -# pipenv -# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. -# However, in case of collaboration, if having platform-specific dependencies or dependencies -# having no cross-platform support, pipenv may install dependencies that don't work, or not -# install all needed dependencies. -#Pipfile.lock - -# UV -# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control. -# This is especially recommended for binary packages to ensure reproducibility, and is more -# commonly ignored for libraries. -#uv.lock - -# poetry -# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. -# This is especially recommended for binary packages to ensure reproducibility, and is more -# commonly ignored for libraries. -# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control -#poetry.lock -#poetry.toml - -# pdm -# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. -# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python. -# https://pdm-project.org/en/latest/usage/project/#working-with-version-control -#pdm.lock -#pdm.toml -.pdm-python -.pdm-build/ - -# pixi -# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control. -#pixi.lock -# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one -# in the .venv directory. It is recommended not to include this directory in version control. -.pixi - -# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm -__pypackages__/ - -# Celery stuff -celerybeat-schedule -celerybeat.pid - -# SageMath parsed files -*.sage.py - -# Environments -.env -.envrc -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ -.dmypy.json -dmypy.json - -# Pyre type checker -.pyre/ - -# pytype static type analyzer -.pytype/ - -# Cython debug symbols -cython_debug/ - -# PyCharm -# JetBrains specific template is maintained in a separate JetBrains.gitignore that can -# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore -# and can be added to the global gitignore or merged into this file. For a more nuclear -# option (not recommended) you can uncomment the following to ignore the entire idea folder. -#.idea/ - -# Abstra -# Abstra is an AI-powered process automation framework. -# Ignore directories containing user credentials, local state, and settings. -# Learn more at https://abstra.io/docs -.abstra/ - -# Visual Studio Code -# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore -# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore -# and can be added to the global gitignore or merged into this file. However, if you prefer, -# you could uncomment the following to ignore the entire vscode folder -# .vscode/ - -# Ruff stuff: -.ruff_cache/ - -# PyPI configuration file -.pypirc - -# Cursor -# Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to -# exclude from AI features like autocomplete and code analysis. Recommended for sensitive data -# refer to https://docs.cursor.com/context/ignore-files -.cursorignore -.cursorindexingignore - -# Marimo -marimo/_static/ -marimo/_lsp/ -__marimo__/ - #项目自忽略 -frontend/react-app/node_modules/ +frontend/node_modules/ +frontend/build/ .vscode diff --git a/backend/.env b/backend/.env new file mode 100644 index 00000000..2e37e79d --- /dev/null +++ b/backend/.env @@ -0,0 +1,16 @@ +# InfoGenie 环境变量配置文件 +# 请勿将此文件提交到版本控制系统 + +# 邮件配置 +# 请将下面的邮箱地址替换为您的实际QQ邮箱 +MAIL_USERNAME=3205788256@qq.com +MAIL_PASSWORD=szcaxvbftusqddhi + +# 数据库配置 +MONGO_URI=mongodb://shumengya:tyh%4019900420@47.108.90.0:27018/InfoGenie?authSource=admin + +# 应用密钥 +SECRET_KEY=infogenie-secret-key-2025 + +# 环境配置 +FLASK_ENV=development diff --git a/backend/__pycache__/app.cpython-313.pyc b/backend/__pycache__/app.cpython-313.pyc new file mode 100644 index 00000000..c6b36ce5 Binary files /dev/null and b/backend/__pycache__/app.cpython-313.pyc differ diff --git a/backend/__pycache__/config.cpython-313.pyc b/backend/__pycache__/config.cpython-313.pyc new file mode 100644 index 00000000..c5850543 Binary files /dev/null and b/backend/__pycache__/config.cpython-313.pyc differ diff --git a/backend/app.py b/backend/app.py index 24528ab0..1975c060 100755 --- a/backend/app.py +++ b/backend/app.py @@ -16,11 +16,8 @@ import secrets # 导入模块 from modules.auth import auth_bp -from modules.api_60s import api_60s_bp from modules.user_management import user_bp from modules.email_service import init_mail -from modules.smallgame import smallgame_bp -from modules.aimodelapp import aimodelapp_bp from config import Config @@ -43,10 +40,7 @@ def create_app(): # 注册蓝图 app.register_blueprint(auth_bp, url_prefix='/api/auth') - app.register_blueprint(api_60s_bp, url_prefix='/api/60s') app.register_blueprint(user_bp, url_prefix='/api/user') - app.register_blueprint(smallgame_bp, url_prefix='/api/smallgame') - app.register_blueprint(aimodelapp_bp, url_prefix='/api/aimodelapp') # 基础路由 @app.route('/') diff --git a/backend/config.py b/backend/config.py index 0c2fe3ea..da162388 100755 --- a/backend/config.py +++ b/backend/config.py @@ -27,6 +27,9 @@ class Config: SESSION_COOKIE_SECURE = False # 开发环境设为False,生产环境设为True SESSION_COOKIE_HTTPONLY = True SESSION_COOKIE_SAMESITE = 'Lax' + SESSION_COOKIE_DOMAIN = None # 开发环境设为None,生产环境设为具体域名 + SESSION_COOKIE_PATH = '/' + SESSION_REFRESH_EACH_REQUEST = True # 每次请求刷新会话过期时间 # 邮件配置 MAIL_SERVER = 'smtp.qq.com' diff --git a/backend/modules/__pycache__/aimodelapp.cpython-313.pyc b/backend/modules/__pycache__/aimodelapp.cpython-313.pyc new file mode 100644 index 00000000..91ce0c63 Binary files /dev/null and b/backend/modules/__pycache__/aimodelapp.cpython-313.pyc differ diff --git a/backend/modules/__pycache__/api_60s.cpython-313.pyc b/backend/modules/__pycache__/api_60s.cpython-313.pyc new file mode 100644 index 00000000..dd7dd5b8 Binary files /dev/null and b/backend/modules/__pycache__/api_60s.cpython-313.pyc differ diff --git a/backend/modules/__pycache__/api_scanner.cpython-313.pyc b/backend/modules/__pycache__/api_scanner.cpython-313.pyc new file mode 100644 index 00000000..27fd75a6 Binary files /dev/null and b/backend/modules/__pycache__/api_scanner.cpython-313.pyc differ diff --git a/backend/modules/__pycache__/auth.cpython-313.pyc b/backend/modules/__pycache__/auth.cpython-313.pyc new file mode 100644 index 00000000..51dc2f2b Binary files /dev/null and b/backend/modules/__pycache__/auth.cpython-313.pyc differ diff --git a/backend/modules/__pycache__/email_service.cpython-313.pyc b/backend/modules/__pycache__/email_service.cpython-313.pyc new file mode 100644 index 00000000..5a86642c Binary files /dev/null and b/backend/modules/__pycache__/email_service.cpython-313.pyc differ diff --git a/backend/modules/__pycache__/smallgame.cpython-313.pyc b/backend/modules/__pycache__/smallgame.cpython-313.pyc new file mode 100644 index 00000000..294cb898 Binary files /dev/null and b/backend/modules/__pycache__/smallgame.cpython-313.pyc differ diff --git a/backend/modules/__pycache__/user_management.cpython-313.pyc b/backend/modules/__pycache__/user_management.cpython-313.pyc new file mode 100644 index 00000000..dc78a492 Binary files /dev/null and b/backend/modules/__pycache__/user_management.cpython-313.pyc differ diff --git a/backend/modules/aimodelapp.py b/backend/modules/aimodelapp.py deleted file mode 100755 index cbcbcc1f..00000000 --- a/backend/modules/aimodelapp.py +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -""" -AI应用模块 - 提供AI应用静态文件服务和目录扫描 -Created by: 神奇万事通 -Date: 2025-09-02 -""" - -from flask import Blueprint, jsonify -import os - -aimodelapp_bp = Blueprint('aimodelapp', __name__) - -@aimodelapp_bp.route('/scan-directories', methods=['GET']) -def scan_directories(): - """扫描aimodelapp目录结构""" - try: - # 获取项目根目录 - project_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) - ai_directory = os.path.join(project_root, 'frontend', 'aimodelapp') - - if not os.path.exists(ai_directory): - return jsonify({ - 'success': False, - 'message': 'aimodelapp目录不存在' - }), 404 - - apps = [] - - # 颜色渐变配置 - gradient_colors = [ - 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)', - 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)', - 'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)', - 'linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)', - 'linear-gradient(135deg, #fa709a 0%, #fee140 100%)' - ] - - # 扫描目录 - for i, app_name in enumerate(os.listdir(ai_directory)): - app_path = os.path.join(ai_directory, app_name) - index_path = os.path.join(app_path, 'index.html') - - if os.path.isdir(app_path) and os.path.exists(index_path) and not app_name.endswith('.txt'): - # 读取HTML文件获取标题 - try: - with open(index_path, 'r', encoding='utf-8') as f: - html_content = f.read() - title_match = html_content.find('') - if title_match != -1: - title_end = html_content.find('', title_match) - if title_end != -1: - title = html_content[title_match + 7:title_end].strip() - else: - title = app_name - else: - title = app_name - except: - title = app_name - - apps.append({ - 'title': title, - 'description': f'{app_name}AI应用', - 'link': f'/aimodelapp/{app_name}/index.html', - 'status': 'active', - 'color': gradient_colors[i % len(gradient_colors)] - }) - - return jsonify({ - 'success': True, - 'apps': apps - }) - - except Exception as e: - return jsonify({ - 'success': False, - 'message': f'扫描目录时出错: {str(e)}' - }), 500 \ No newline at end of file diff --git a/backend/modules/api_60s.py b/backend/modules/api_60s.py deleted file mode 100755 index 5b520bb6..00000000 --- a/backend/modules/api_60s.py +++ /dev/null @@ -1,103 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -""" -60s API模块 - 提供各种实时数据接口 -Created by: 神奇万事通 -Date: 2025-09-02 -""" - -from flask import Blueprint, jsonify -import os - -api_60s_bp = Blueprint('api_60s', __name__) - -@api_60s_bp.route('/scan-directories', methods=['GET']) -def scan_directories(): - """扫描60sapi目录结构""" - try: - # 获取项目根目录 - project_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) - api_directory = os.path.join(project_root, 'frontend', '60sapi') - - if not os.path.exists(api_directory): - return jsonify({ - 'success': False, - 'message': '60sapi目录不存在' - }), 404 - - categories = [] - - # 定义分类配置 - category_config = { - '热搜榜单': {'color': '#66bb6a'}, - '日更资讯': {'color': '#4caf50'}, - '实用功能': {'color': '#388e3c'}, - '娱乐消遣': {'color': '#66bb6a'} - } - - # 颜色渐变配置 - gradient_colors = [ - 'linear-gradient(135deg, #81c784 0%, #66bb6a 100%)', - 'linear-gradient(135deg, #a5d6a7 0%, #81c784 100%)', - 'linear-gradient(135deg, #c8e6c9 0%, #a5d6a7 100%)', - 'linear-gradient(135deg, #66bb6a 0%, #4caf50 100%)', - 'linear-gradient(135deg, #4caf50 0%, #388e3c 100%)' - ] - - # 扫描目录 - for category_name in os.listdir(api_directory): - category_path = os.path.join(api_directory, category_name) - - if os.path.isdir(category_path) and category_name in category_config: - apis = [] - - # 扫描分类下的模块 - for i, module_name in enumerate(os.listdir(category_path)): - module_path = os.path.join(category_path, module_name) - index_path = os.path.join(module_path, 'index.html') - - if os.path.isdir(module_path) and os.path.exists(index_path): - # 读取HTML文件获取标题 - try: - with open(index_path, 'r', encoding='utf-8') as f: - html_content = f.read() - title_match = html_content.find('') - if title_match != -1: - title_end = html_content.find('', title_match) - if title_end != -1: - title = html_content[title_match + 7:title_end].strip() - else: - title = module_name - else: - title = module_name - except: - title = module_name - - # 根据环境获取基础URL - base_url = 'https://infogenie.api.shumengya.top' - - apis.append({ - 'title': title, - 'description': f'{module_name}相关功能', - 'link': f'{base_url}/60sapi/{category_name}/{module_name}/index.html', - 'status': 'active', - 'color': gradient_colors[i % len(gradient_colors)] - }) - - if apis: - categories.append({ - 'title': category_name, - 'color': category_config[category_name]['color'], - 'apis': apis - }) - - return jsonify({ - 'success': True, - 'categories': categories - }) - - except Exception as e: - return jsonify({ - 'success': False, - 'message': f'扫描目录时出错: {str(e)}' - }), 500 diff --git a/backend/modules/auth.py b/backend/modules/auth.py index 5a724f50..96fd48d4 100755 --- a/backend/modules/auth.py +++ b/backend/modules/auth.py @@ -10,11 +10,53 @@ from flask import Blueprint, request, jsonify, session, current_app from werkzeug.security import generate_password_hash, check_password_hash import hashlib import re -from datetime import datetime +import jwt +from datetime import datetime, timedelta +from functools import wraps from .email_service import send_verification_email, verify_code, is_qq_email, get_qq_avatar_url auth_bp = Blueprint('auth', __name__) +def generate_token(user_data): + """生成JWT token""" + payload = { + 'user_id': user_data['user_id'], + 'email': user_data['email'], + 'username': user_data['username'], + 'exp': datetime.utcnow() + timedelta(days=7), # 7天过期 + 'iat': datetime.utcnow() + } + return jwt.encode(payload, current_app.config['SECRET_KEY'], algorithm='HS256') + +def verify_token(token): + """验证JWT token""" + try: + payload = jwt.decode(token, current_app.config['SECRET_KEY'], algorithms=['HS256']) + return {'success': True, 'data': payload} + except jwt.ExpiredSignatureError: + return {'success': False, 'message': 'Token已过期'} + except jwt.InvalidTokenError: + return {'success': False, 'message': 'Token无效'} + +def token_required(f): + """JWT token验证装饰器""" + @wraps(f) + def decorated(*args, **kwargs): + token = request.headers.get('Authorization') + if not token: + return jsonify({'success': False, 'message': '缺少认证token'}), 401 + + if token.startswith('Bearer '): + token = token[7:] + + result = verify_token(token) + if not result['success']: + return jsonify({'success': False, 'message': result['message']}), 401 + + request.current_user = result['data'] + return f(*args, **kwargs) + return decorated + def validate_qq_email(email): """验证QQ邮箱格式""" return is_qq_email(email) @@ -313,16 +355,18 @@ def login(): } ) - # 设置会话 - session['user_id'] = str(user['_id']) - session['email'] = email - session['username'] = user.get('用户名', '') - session['logged_in'] = True - session.permanent = True - + # 生成JWT token + user_data = { + 'user_id': str(user['_id']), + 'email': email, + 'username': user.get('用户名', '') + } + token = generate_token(user_data) + return jsonify({ 'success': True, 'message': '登录成功!', + 'token': token, 'user': { 'id': str(user['_id']), 'email': email, @@ -373,17 +417,11 @@ def login(): def logout(): """用户登出""" try: - if 'logged_in' in session: - session.clear() - return jsonify({ - 'success': True, - 'message': '已成功登出' - }), 200 - else: - return jsonify({ - 'success': False, - 'message': '用户未登录' - }), 401 + # JWT是无状态的,客户端删除token即可 + return jsonify({ + 'success': True, + 'message': '已成功登出' + }), 200 except Exception as e: return jsonify({ @@ -395,14 +433,26 @@ def logout(): def check_login(): """检查登录状态""" try: - if session.get('logged_in') and session.get('user_id'): + token = request.headers.get('Authorization') + if not token: + return jsonify({ + 'success': True, + 'logged_in': False + }), 200 + + if token.startswith('Bearer '): + token = token[7:] + + result = verify_token(token) + if result['success']: + user_data = result['data'] return jsonify({ 'success': True, 'logged_in': True, 'user': { - 'id': session.get('user_id'), - 'email': session.get('email'), - 'username': session.get('username') + 'id': user_data['user_id'], + 'email': user_data['email'], + 'username': user_data['username'] } }), 200 else: diff --git a/backend/modules/smallgame.py b/backend/modules/smallgame.py deleted file mode 100755 index 90c28220..00000000 --- a/backend/modules/smallgame.py +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -""" -小游戏模块 - 提供小游戏静态文件服务和目录扫描 -Created by: 神奇万事通 -Date: 2025-09-02 -""" - -from flask import Blueprint, jsonify -import os - -smallgame_bp = Blueprint('smallgame', __name__) - -@smallgame_bp.route('/scan-directories', methods=['GET']) -def scan_directories(): - """扫描smallgame目录结构""" - try: - # 获取项目根目录 - project_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) - game_directory = os.path.join(project_root, 'frontend', 'smallgame') - - if not os.path.exists(game_directory): - return jsonify({ - 'success': False, - 'message': 'smallgame目录不存在' - }), 404 - - games = [] - - # 颜色渐变配置 - gradient_colors = [ - 'linear-gradient(135deg, #ff9a9e 0%, #fecfef 100%)', - 'linear-gradient(135deg, #a8edea 0%, #fed6e3 100%)', - 'linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%)', - 'linear-gradient(135deg, #ff8a80 0%, #ffab91 100%)', - 'linear-gradient(135deg, #81c784 0%, #aed581 100%)' - ] - - # 扫描目录 - for i, game_name in enumerate(os.listdir(game_directory)): - game_path = os.path.join(game_directory, game_name) - index_path = os.path.join(game_path, 'index.html') - - if os.path.isdir(game_path) and os.path.exists(index_path) and not game_name.endswith('.txt'): - # 读取HTML文件获取标题 - try: - with open(index_path, 'r', encoding='utf-8') as f: - html_content = f.read() - title_match = html_content.find('') - if title_match != -1: - title_end = html_content.find('', title_match) - if title_end != -1: - title = html_content[title_match + 7:title_end].strip() - else: - title = game_name - else: - title = game_name - except: - title = game_name - - games.append({ - 'title': title, - 'description': f'{game_name}小游戏', - 'link': f'/smallgame/{game_name}/index.html', - 'status': 'active', - 'color': gradient_colors[i % len(gradient_colors)] - }) - - return jsonify({ - 'success': True, - 'games': games - }) - - except Exception as e: - return jsonify({ - 'success': False, - 'message': f'扫描目录时出错: {str(e)}' - }), 500 \ No newline at end of file diff --git a/backend/requirements.txt b/backend/requirements.txt index ba9ba09c..3a6a4eaf 100755 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -10,6 +10,9 @@ pymongo==4.5.0 # 密码加密 Werkzeug==2.3.7 +# JWT认证 +PyJWT==2.8.0 + # HTTP请求 requests==2.31.0 diff --git a/frontend/60sapi/娱乐消遣/随机JavaScript趣味题/css/background.css b/frontend/60sapi/娱乐消遣/随机JavaScript趣味题/css/background.css deleted file mode 100755 index 7a44dec9..00000000 --- a/frontend/60sapi/娱乐消遣/随机JavaScript趣味题/css/background.css +++ /dev/null @@ -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); - } -} \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机JavaScript趣味题/css/style.css b/frontend/60sapi/娱乐消遣/随机JavaScript趣味题/css/style.css deleted file mode 100755 index 2ad05653..00000000 --- a/frontend/60sapi/娱乐消遣/随机JavaScript趣味题/css/style.css +++ /dev/null @@ -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; - } -} \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机JavaScript趣味题/index.html b/frontend/60sapi/娱乐消遣/随机JavaScript趣味题/index.html deleted file mode 100755 index b3d01b4e..00000000 --- a/frontend/60sapi/娱乐消遣/随机JavaScript趣味题/index.html +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - 随机JavaScript趣味题 - - - - - - - - - -
-
-

JavaScript趣味题

-

测试你的JavaScript知识

-
- -
-
-
-

正在加载题目...

-
- - - - -
- - -
- - - - \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机JavaScript趣味题/js/script.js b/frontend/60sapi/娱乐消遣/随机JavaScript趣味题/js/script.js deleted file mode 100755 index 891da9e4..00000000 --- a/frontend/60sapi/娱乐消遣/随机JavaScript趣味题/js/script.js +++ /dev/null @@ -1,582 +0,0 @@ -// JavaScript趣味题应用 -class JSQuizApp { - constructor() { - this.apiEndpoints = [ - 'https://60s.api.shumengya.top', - ]; - this.currentApiIndex = 0; - this.currentQuestion = null; - this.selectedOption = null; - this.isAnswered = false; - this.loadStartTime = null; - - this.initElements(); - this.bindEvents(); - this.preloadResources(); - 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') - }; - } - - // 预加载资源 - preloadResources() { - // 预连接API服务器 - this.apiEndpoints.forEach(endpoint => { - const link = document.createElement('link'); - link.rel = 'preconnect'; - link.href = endpoint; - document.head.appendChild(link); - }); - } - - // 绑定事件 - 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.loadStartTime = Date.now(); - this.showLoading(); - this.resetQuestion(); - - let attempts = 0; - const maxAttempts = this.apiEndpoints.length; - - while (attempts < maxAttempts) { - try { - const controller = new AbortController(); - const timeoutId = setTimeout(() => controller.abort(), 5000); - - const response = await fetch(this.getCurrentApiUrl(), { - 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) { - this.currentQuestion = data.data; - const loadTime = Date.now() - this.loadStartTime; - console.log(`题目加载完成,耗时: ${loadTime}ms`); - 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 = `

${this.escapeHtml(question.question)}

`; - - // 设置代码内容并应用语法高亮 - 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, '
$1
'); - formatted = formatted.replace(/```javascript\n([\s\S]*?)\n```/g, '
$1
'); - formatted = formatted.replace(/```([\s\S]*?)```/g, '
$1
'); - - // 处理行内代码 - formatted = formatted.replace(/`([^`]+)`/g, '$1'); - - // 处理换行 - formatted = formatted.replace(/\n\n/g, '

'); - formatted = formatted.replace(/\n/g, '
'); - - // 包装段落 - if (!formatted.includes('

')) { - formatted = '

' + formatted + '

'; - } - - 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(//gi, '\n'); - explanation = explanation.replace(/

/gi, '\n'); - explanation = explanation.replace(/<\/p>/gi, '\n'); - explanation = explanation.replace(/]*>/gi, '`'); - explanation = explanation.replace(/<\/code>/gi, '`'); - explanation = explanation.replace(/

/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 = `
-            
- - - -
-
导出成功!
-
${filename}
-
-
- `; - - // 添加动画样式 - 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('网络连接已断开'); - }); -} \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机JavaScript趣味题/接口集合.json b/frontend/60sapi/娱乐消遣/随机JavaScript趣味题/接口集合.json deleted file mode 100755 index 547b2771..00000000 --- a/frontend/60sapi/娱乐消遣/随机JavaScript趣味题/接口集合.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "https://60s.api.shumengya.top" -] diff --git a/frontend/60sapi/娱乐消遣/随机JavaScript趣味题/返回接口.json b/frontend/60sapi/娱乐消遣/随机JavaScript趣味题/返回接口.json deleted file mode 100755 index d6592cc8..00000000 --- a/frontend/60sapi/娱乐消遣/随机JavaScript趣味题/返回接口.json +++ /dev/null @@ -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` 实例都需要这个方法。这将浪费大量内存空间,因为它们仍然具有该属性,这将占用每个实例的内存空间。相反,如果我们只将它添加到原型中,那么它只存在于内存中的一个位置,但是所有实例都可以访问它!" - } -} \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机KFC文案/css/background.css b/frontend/60sapi/娱乐消遣/随机KFC文案/css/background.css deleted file mode 100755 index 84d3b43d..00000000 --- a/frontend/60sapi/娱乐消遣/随机KFC文案/css/background.css +++ /dev/null @@ -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; - } -} \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机KFC文案/css/style.css b/frontend/60sapi/娱乐消遣/随机KFC文案/css/style.css deleted file mode 100755 index b1bef2cc..00000000 --- a/frontend/60sapi/娱乐消遣/随机KFC文案/css/style.css +++ /dev/null @@ -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; - } -} \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机KFC文案/index.html b/frontend/60sapi/娱乐消遣/随机KFC文案/index.html deleted file mode 100755 index 72ab0627..00000000 --- a/frontend/60sapi/娱乐消遣/随机KFC文案/index.html +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - 随机KFC文案生成器 - - - - -
-
-

🍗 随机KFC文案生成器

-

疯狂星期四,文案来一套!

-
- -
-
-
-

点击按钮获取随机KFC文案...

-
- -
- - -
- - -
-
- -
-

© 2024 KFC文案生成器 | 让每个星期四都疯狂起来

-
-
- -
- - - - \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机KFC文案/js/main.js b/frontend/60sapi/娱乐消遣/随机KFC文案/js/main.js deleted file mode 100755 index 353209f9..00000000 --- a/frontend/60sapi/娱乐消遣/随机KFC文案/js/main.js +++ /dev/null @@ -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 { - // 直接硬编码API端点,避免CORS问题 - this.apiEndpoints = ["https://60s.api.shumengya.top"]; - } 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 = `

${this.escapeHtml(data.kfc)}

`; - - // 显示编号信息 - 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 = `

${this.escapeHtml(message)}

`; - - 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(); - } - } -}); \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机KFC文案/接口集合.json b/frontend/60sapi/娱乐消遣/随机KFC文案/接口集合.json deleted file mode 100755 index 547b2771..00000000 --- a/frontend/60sapi/娱乐消遣/随机KFC文案/接口集合.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "https://60s.api.shumengya.top" -] diff --git a/frontend/60sapi/娱乐消遣/随机KFC文案/返回接口.json b/frontend/60sapi/娱乐消遣/随机KFC文案/返回接口.json deleted file mode 100755 index 1e04caca..00000000 --- a/frontend/60sapi/娱乐消遣/随机KFC文案/返回接口.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "code": 200, - "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", - "data": { - "index": 78, - "kfc": "我叫夯大力 立冬给我准备了糖炒栗子了没有 没准备的自动绝交 再 v 我 50 吃疯狂星期四 然后再给我点杯奶茶 再给我两万块钱 懂吗你们" - } -} \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机一言/css/background.css b/frontend/60sapi/娱乐消遣/随机一言/css/background.css deleted file mode 100755 index 3a10cfda..00000000 --- a/frontend/60sapi/娱乐消遣/随机一言/css/background.css +++ /dev/null @@ -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%); - } -} \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机一言/css/style.css b/frontend/60sapi/娱乐消遣/随机一言/css/style.css deleted file mode 100755 index b84b1125..00000000 --- a/frontend/60sapi/娱乐消遣/随机一言/css/style.css +++ /dev/null @@ -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; - } -} \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机一言/index.html b/frontend/60sapi/娱乐消遣/随机一言/index.html deleted file mode 100755 index 4ef88f30..00000000 --- a/frontend/60sapi/娱乐消遣/随机一言/index.html +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - 随机一言 - 金色光辉 - - - - -
-
-

随机一言

-

每一句话都是心灵的光芒

-
- -
-
-
-
-

正在获取一言...

-
- -
-
- 点击下方按钮获取一言 -
-
-
- -
-
⚠️
-
-
-
- -
- -
-
- -
-

愿每一句话都能温暖你的心

-
-
- - - - \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机一言/js/script.js b/frontend/60sapi/娱乐消遣/随机一言/js/script.js deleted file mode 100755 index cd62af76..00000000 --- a/frontend/60sapi/娱乐消遣/随机一言/js/script.js +++ /dev/null @@ -1,222 +0,0 @@ -// 随机一言 JavaScript 功能实现 - -class HitokotoApp { - constructor() { - // API接口列表 - this.apiEndpoints = [ - "https://60s.api.shumengya.top" - ]; - - 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 { - // 移除URL中的encoding=text参数,确保返回JSON格式 - const response = await fetch(`${endpoint}/v2/hitokoto`, { - 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; -} \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机一言/接口集合.json b/frontend/60sapi/娱乐消遣/随机一言/接口集合.json deleted file mode 100755 index 547b2771..00000000 --- a/frontend/60sapi/娱乐消遣/随机一言/接口集合.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "https://60s.api.shumengya.top" -] diff --git a/frontend/60sapi/娱乐消遣/随机一言/返回接口.json b/frontend/60sapi/娱乐消遣/随机一言/返回接口.json deleted file mode 100755 index 29342ebc..00000000 --- a/frontend/60sapi/娱乐消遣/随机一言/返回接口.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "code": 200, - "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", - "data": { - "index": 2862, - "hitokoto": "你带上罪恶之冠,即使背负上所有罪恶和孤独,绝不让你受伤" - } -} \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机冷笑话/css/Untitled-1.html b/frontend/60sapi/娱乐消遣/随机冷笑话/css/Untitled-1.html deleted file mode 100755 index 6edd77e5..00000000 --- a/frontend/60sapi/娱乐消遣/随机冷笑话/css/Untitled-1.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - 每日笑话 - - - -
-

加载中...

- -
- - - \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机冷笑话/css/background.css b/frontend/60sapi/娱乐消遣/随机冷笑话/css/background.css deleted file mode 100755 index 79480464..00000000 --- a/frontend/60sapi/娱乐消遣/随机冷笑话/css/background.css +++ /dev/null @@ -1,107 +0,0 @@ -/* background.css - 动态渐变背景 */ -body { - background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab); - background-size: 400% 400%; - animation: gradient 15s ease infinite; -} - -@keyframes gradient { - 0% { - background-position: 0% 50%; - } - 50% { - background-position: 100% 50%; - } - 100% { - background-position: 0% 50%; - } -} -:root { - --bg-yellow: #FFFDE7; /* 浅黄 */ - --bg-blue: #E3F2FD; /* 淡蓝 */ -} - -body { - background: linear-gradient(180deg, var(--bg-yellow) 0%, var(--bg-blue) 100%); - background-attachment: fixed; /* 固定背景,滚动时不移动 */ -} - -body { - margin: 0; - padding: 0; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; - overflow: hidden; - transition: background-color 0.5s ease; -} - -/* Light Theme (Default) */ -[data-theme="light"] { - background: linear-gradient(to bottom, #87CEEB, #B0E0E6); -} - -/* Dark Theme */ -[data-theme="dark"] { - background: linear-gradient(to bottom, #232526, #414345); -} -[data-theme="dark"] .snowflake { - color: #999; -} - -/* Winter Theme */ -[data-theme="winter"] { - background: linear-gradient(to bottom, #a1c4fd, #c2e9fb); -} -[data-theme="winter"] .background-bottom { - position: fixed; - bottom: 0; - left: 0; - width: 100%; - height: 100px; - background: linear-gradient(to top, white, rgba(255, 255, 255, 0)); - z-index: -1; - border-radius: 50% 50% 0 0 / 20px; - box-shadow: 0 -10px 20px rgba(255, 255, 255, 0.5); -} - - -#snowflake-container { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - pointer-events: none; - z-index: 0; -} - -.snowflake { - position: absolute; - top: -10%; - color: white; - font-size: 20px; - user-select: none; - animation: fall linear infinite; -} - -@keyframes fall { - to { - transform: translateY(105vh) rotate(360deg); - } -} - -#frost-overlay { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: url('https://www.transparenttextures.com/patterns/ice-age.png') repeat; - opacity: 0; - pointer-events: none; - transition: opacity 0.5s ease-in-out; - z-index: 100; -} - -#frost-overlay.is-frosted { - opacity: 0.3; -} \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机冷笑话/css/style.css b/frontend/60sapi/娱乐消遣/随机冷笑话/css/style.css deleted file mode 100755 index 1676dffd..00000000 --- a/frontend/60sapi/娱乐消遣/随机冷笑话/css/style.css +++ /dev/null @@ -1,217 +0,0 @@ -:root { - --primary-color-light: #4A90E2; - --text-color-light: #333; - --card-bg-light: rgba(255, 255, 255, 0.85); - - --primary-color-dark: #5271C4; - --text-color-dark: #E0E0E0; - --card-bg-dark: rgba(40, 40, 40, 0.85); - - --primary-color-winter: #6A82FB; - --text-color-winter: #2c3e50; - --card-bg-winter: rgba(255, 255, 255, 0.7); -} - -.container { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - min-height: 100vh; - padding: 20px; - box-sizing: border-box; - text-align: center; - position: relative; - z-index: 1; -} - -.top-nav { - position: absolute; - top: 20px; - right: 20px; - background: rgba(255, 255, 255, 0.3); - padding: 5px; - border-radius: 50px; - backdrop-filter: blur(5px); -} - -.theme-switcher { - display: flex; - gap: 5px; -} - -.theme-btn { - background: transparent; - border: 2px solid transparent; - border-radius: 50%; - width: 40px; - height: 40px; - font-size: 1.5em; - cursor: pointer; - transition: transform 0.2s, border-color 0.2s; -} -.theme-btn:hover { - transform: scale(1.1); -} -.theme-btn.active { - border-color: white; -} - -.title { - font-family: 'ZCOOL KuaiLe', cursive; - font-size: 3em; - margin-bottom: 20px; - transition: color 0.5s ease; -} - -.joke-stream { - width: 100%; - max-width: 500px; - display: flex; - flex-direction: column; - gap: 25px; -} - -.joke-card { - border-radius: 20px; - padding: 30px 40px; - box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15); - width: 100%; - max-width: 500px; - min-height: 150px; - display: flex; - justify-content: center; - align-items: center; - position: relative; - backdrop-filter: blur(8px); - border: 1px solid rgba(255, 255, 255, 0.2); - transition: background-color 0.5s ease, border-color 0.5s ease; -} - -#joke-text { - font-size: 1.5em; - line-height: 1.6; - transition: opacity 0.3s, color 0.5s ease; -} - -/* --- Theming --- */ - -/* Light Theme */ -[data-theme="light"] .title { color: white; text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2); } -[data-theme="light"] .joke-card { background-color: var(--card-bg-light); } -[data-theme="light"] #joke-text { color: var(--text-color-light); } -[data-theme="light"] #new-joke-btn { background-color: var(--primary-color-light); box-shadow: 0 4px 15px rgba(74, 144, 226, 0.4); } -[data-theme="light"] footer { color: rgba(255, 255, 255, 0.8); } - -/* Dark Theme */ -[data-theme="dark"] .title { color: #EAEAEA; text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5); } -[data-theme="dark"] .joke-card { background-color: var(--card-bg-dark); border-color: rgba(255, 255, 255, 0.1); } -[data-theme="dark"] #joke-text { color: var(--text-color-dark); } -[data-theme="dark"] #new-joke-btn { background-color: var(--primary-color-dark); box-shadow: 0 4px 15px rgba(82, 113, 196, 0.4); } -[data-theme="dark"] footer { color: rgba(200, 200, 200, 0.7); } - -/* Winter Theme */ -[data-theme="winter"] .title { color: #1e3a5f; text-shadow: 1px 1px 2px rgba(255, 255, 255, 0.7); } -[data-theme="winter"] .joke-card { - background-color: var(--card-bg-winter); - border-color: rgba(255, 255, 255, 0.8); - box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1), inset 0 0 15px rgba(255, 255, 255, 0.5); -} -[data-theme="winter"] #joke-text { color: var(--text-color-winter); } -[data-theme="winter"] #new-joke-btn { background-color: var(--primary-color-winter); box-shadow: 0 4px 15px rgba(106, 130, 251, 0.4); } -[data-theme="winter"] footer { color: #1e3a5f; } - - -.controls { - margin-top: 30px; -} - -#new-joke-btn { - color: white; - font-size: 1.2em; - font-weight: bold; - padding: 15px 35px; - border: none; - border-radius: 50px; - cursor: pointer; - transition: transform 0.2s ease, box-shadow 0.2s ease, background-color 0.5s ease; -} - -#new-joke-btn:hover { - transform: translateY(-3px); -} - -#new-joke-btn:active { - transform: translateY(1px); -} - -.interactions { - margin-top: 25px; - display: flex; - gap: 20px; -} - -.interaction-btn { - background: rgba(255, 255, 255, 0.7); - border: 1px solid rgba(255, 255, 255, 0.9); - border-radius: 50%; - width: 50px; - height: 50px; - font-size: 1.5em; - cursor: pointer; - transition: transform 0.2s, background-color 0.2s; -} - -.interaction-btn:hover { - transform: scale(1.1); - background: white; -} - -footer { - position: absolute; - bottom: 10px; - font-size: 0.9em; - transition: color 0.5s ease; -} - -/* Loader */ -#loader { - position: absolute; - transition: color 0.5s ease; -} -[data-theme="light"] #loader { color: var(--primary-color-light); } -[data-theme="dark"] #loader { color: var(--primary-color-dark); } -[data-theme="winter"] #loader { color: var(--primary-color-winter); } - -.snowflake-loader { - font-size: 40px; - display: inline-block; - animation: spin 1.5s linear infinite; -} -.snowflake-loader::before { - content: '❄'; -} -@keyframes spin { - to { transform: rotate(360deg); } -} - -.hidden { - display: none; -} - -/* Responsive */ -@media (max-width: 600px) { - .title { - font-size: 2.5em; - } - .joke-card { - padding: 25px; - } - #joke-text { - font-size: 1.2em; - } - .top-nav { - top: 10px; - right: 10px; - } -} \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机冷笑话/index.html b/frontend/60sapi/娱乐消遣/随机冷笑话/index.html deleted file mode 100755 index 68477bd1..00000000 --- a/frontend/60sapi/娱乐消遣/随机冷笑话/index.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - 随机冷笑话 - - - - - -
-
-
- - - -
-
-

冷笑话生成器

-
- -
- -

点击下面的按钮,来点冷笑话吧!

-
- -
- -
- -
- - - - -
-
- -
-

© 2024 冷笑话工坊

-
- - - - - - - \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机冷笑话/js/script.js b/frontend/60sapi/娱乐消遣/随机冷笑话/js/script.js deleted file mode 100755 index 8fe675eb..00000000 --- a/frontend/60sapi/娱乐消遣/随机冷笑话/js/script.js +++ /dev/null @@ -1,117 +0,0 @@ -document.addEventListener('DOMContentLoaded', () => { - const jokeTextElem = document.getElementById('joke-text'); - const newJokeBtn = document.getElementById('new-joke-btn'); - const snowflakeContainer = document.getElementById('snowflake-container'); - const frostOverlay = document.getElementById('frost-overlay'); - const windSound = document.getElementById('wind-sound'); - const snowSound = document.getElementById('snow-sound'); - const loader = document.getElementById('loader'); - const themeBtns = document.querySelectorAll('.theme-btn'); - - const apiEndpoints = [ - 'https://60s.api.shumengya.top/v2/dad-joke', - ]; - let currentApiIndex = 0; - - async function fetchJoke() { - jokeTextElem.classList.add('hidden'); - loader.classList.remove('hidden'); - - try { - const response = await fetch(apiEndpoints[currentApiIndex]); - if (!response.ok) throw new Error('Network response was not ok'); - - const data = await response.json(); - if (data.code === 200 && data.data.content) { - updateJokeText(data.data.content); - if (document.body.dataset.theme === 'winter' && Math.random() < 0.3) { - triggerFrostEffect(); - } - } else { - throw new Error('API returned invalid data'); - } - } catch (error) { - console.error('Fetch error:', error); - currentApiIndex = (currentApiIndex + 1) % apiEndpoints.length; - if (currentApiIndex !== 0) { - fetchJoke(); - } else { - jokeTextElem.textContent = '冰箱坏了,暂时没有冷笑话...'; - } - } finally { - loader.classList.add('hidden'); - jokeTextElem.classList.remove('hidden'); - } - } - - function updateJokeText(text) { - jokeTextElem.textContent = ''; - let i = 0; - const typing = setInterval(() => { - if (i < text.length) { - jokeTextElem.textContent += text.charAt(i); - i++; - } else { - clearInterval(typing); - } - }, 50); - } - - function createSnowflakes() { - const snowflakeCount = document.body.dataset.theme === 'dark' ? 50 : 30; - snowflakeContainer.innerHTML = ''; - for (let i = 0; i < snowflakeCount; i++) { - const snowflake = document.createElement('div'); - snowflake.className = 'snowflake'; - snowflake.textContent = '❄️'; - - snowflake.style.left = `${Math.random() * 100}vw`; - snowflake.style.fontSize = `${Math.random() * 15 + 10}px`; - snowflake.style.opacity = Math.random() * 0.5 + 0.3; - - const duration = Math.random() * 10 + 8; - const delay = Math.random() * 10; - - snowflake.style.animation = `fall ${duration}s linear ${delay}s infinite`; - - snowflakeContainer.appendChild(snowflake); - } - } - - function triggerFrostEffect() { - frostOverlay.classList.add('is-frosted'); - windSound.play().catch(e => console.error("Audio play failed:", e)); - setTimeout(() => { - frostOverlay.classList.remove('is-frosted'); - }, 2000); - } - - function setTheme(theme) { - document.body.dataset.theme = theme; - localStorage.setItem('joke-theme', theme); - - themeBtns.forEach(btn => { - btn.classList.toggle('active', btn.dataset.themeTarget === theme); - }); - - if (theme === 'winter') { - snowSound.play().catch(e => console.error("Audio play failed:", e)); - } - - // Recreate snowflakes for theme-specific density - createSnowflakes(); - } - - themeBtns.forEach(btn => { - btn.addEventListener('click', () => { - setTheme(btn.dataset.themeTarget); - }); - }); - - newJokeBtn.addEventListener('click', fetchJoke); - - // Initial setup - const savedTheme = localStorage.getItem('joke-theme') || 'light'; - setTheme(savedTheme); - fetchJoke(); -}); \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机冷笑话/接口集合.json b/frontend/60sapi/娱乐消遣/随机冷笑话/接口集合.json deleted file mode 100755 index 37dc3082..00000000 --- a/frontend/60sapi/娱乐消遣/随机冷笑话/接口集合.json +++ /dev/null @@ -1 +0,0 @@ -["https://60s.api.shumengya.top"] \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机冷笑话/返回接口.json b/frontend/60sapi/娱乐消遣/随机冷笑话/返回接口.json deleted file mode 100755 index b514f650..00000000 --- a/frontend/60sapi/娱乐消遣/随机冷笑话/返回接口.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "code": 200, - "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", - "data": { - "index": 121, - "content": "这个世界上谁最懂猪?蜘蛛(知猪)人。" - } -} \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机发病文学/css/background.css b/frontend/60sapi/娱乐消遣/随机发病文学/css/background.css deleted file mode 100755 index b77c1a35..00000000 --- a/frontend/60sapi/娱乐消遣/随机发病文学/css/background.css +++ /dev/null @@ -1,90 +0,0 @@ -body { - background-color: #1a1a1a; - color: #e0e0e0; - font-family: 'Courier New', Courier, monospace; - overflow: hidden; - margin: 0; - padding: 0; -} - -#bg-container { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: -2; - overflow: hidden; - transition: transform 0.2s ease-out; -} - -.floating-emoji { - position: absolute; - user-select: none; - opacity: 0; - animation-iteration-count: infinite; - animation-timing-function: linear; -} - -@keyframes float-top-to-bottom { - 0% { transform: translateY(-10vh) rotate(0deg); opacity: 0; } - 10%, 90% { opacity: 0.7; } - 100% { transform: translateY(110vh) rotate(360deg); opacity: 0; } -} - -@keyframes float-bottom-to-top { - 0% { transform: translateY(110vh) rotate(0deg); opacity: 0; } - 10%, 90% { opacity: 0.7; } - 100% { transform: translateY(-10vh) rotate(360deg); opacity: 0; } -} - -@keyframes float-left-to-right { - 0% { transform: translateX(-10vw) rotate(0deg); opacity: 0; } - 10%, 90% { opacity: 0.7; } - 100% { transform: translateX(110vw) rotate(360deg); opacity: 0; } -} - -@keyframes float-right-to-left { - 0% { transform: translateX(110vw) rotate(0deg); opacity: 0; } - 10%, 90% { opacity: 0.7; } - 100% { transform: translateX(-10vw) rotate(360deg); opacity: 0; } -} - -.text-fragment { - position: absolute; - font-size: 24px; - color: rgba(255, 0, 255, 0.4); - opacity: 0; - animation: float-fragment 15s linear infinite, fade-in-out 15s linear infinite; - user-select: none; -} - -@keyframes float-fragment { - 0% { transform: translate(0, 0) rotate(0deg); } - 25% { transform: translate(20px, 40px) rotate(15deg); } - 50% { transform: translate(-30px, -10px) rotate(-10deg); } - 75% { transform: translate(10px, -30px) rotate(5deg); } - 100% { transform: translate(0, 0) rotate(0deg); } -} - -@keyframes fade-in-out { - 0%, 100% { opacity: 0; } - 10%, 90% { opacity: 0.4; } -} - -.screen-crack { - position: absolute; - width: 200px; - height: 200px; - background-image: url('data:image/svg+xml;utf8,'); - opacity: 0; - animation: flicker-crack 25s steps(1, end) infinite; -} - -@keyframes flicker-crack { - 0%, 100% { opacity: 0; } - 50% { opacity: 0.3; } - 51% { opacity: 0; } - 75% { opacity: 0.2; } - 76% { opacity: 0; } -} \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机发病文学/css/style.css b/frontend/60sapi/娱乐消遣/随机发病文学/css/style.css deleted file mode 100755 index db1df76c..00000000 --- a/frontend/60sapi/娱乐消遣/随机发病文学/css/style.css +++ /dev/null @@ -1,235 +0,0 @@ -.container { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - min-height: 100vh; - padding: 20px; - box-sizing: border-box; - position: relative; - z-index: 1; -} - -.content-card { - background: rgba(20, 20, 20, 0.7); - border: none; - padding: 40px; - max-width: 600px; - width: 100%; - text-align: center; - backdrop-filter: blur(5px); - position: relative; - clip-path: polygon(2% 5%, 97% 0%, 100% 95%, 0% 100%); -} - -.body-animated .content-card { - animation: tremble 0.4s infinite, glitch-shadow 1.5s steps(1, end) infinite; -} - -@keyframes tremble { - 0% { clip-path: polygon(2% 5%, 97% 0%, 100% 95%, 0% 100%); } - 25% { clip-path: polygon(2% 5%, 98% 2%, 99% 100%, 1% 98%); } - 50% { clip-path: polygon(3% 4%, 96% 1%, 100% 96%, 2% 100%); } - 75% { clip-path: polygon(1% 6%, 97% 3%, 98% 95%, 0% 99%); } - 100% { clip-path: polygon(2% 5%, 97% 0%, 100% 95%, 0% 100%); } -} - -@keyframes glitch-shadow { - 0% { - box-shadow: - 0 0 8px rgba(255, 0, 255, 0.5), - inset 0 0 8px rgba(255, 0, 255, 0.4); - } - 33% { - box-shadow: - 0 0 8px rgba(0, 255, 255, 0.5), - inset 0 0 8px rgba(0, 255, 255, 0.4); - } - 66% { - box-shadow: - 0 0 8px rgba(0, 255, 0, 0.5), - inset 0 0 8px rgba(0, 255, 0, 0.4); - } - 100% { - box-shadow: - 0 0 8px rgba(255, 0, 255, 0.5), - inset 0 0 8px rgba(255, 0, 255, 0.4); - } -} - -#literature-text { - font-size: 1.2em; - line-height: 1.8; - min-height: 100px; - color: #e0e0e0; - text-shadow: 0 0 5px rgba(0, 255, 135, 0.5); - animation: text-flicker 15s linear infinite; -} - -.body-animated #literature-text { - animation: text-flicker 15s linear infinite, text-shadow-glitch 2s steps(1, end) infinite; -} - -@keyframes text-flicker { - 0%, 100% { opacity: 1; } - 50.0% { opacity: 0.95; } - 50.5% { opacity: 1; } -} - -@keyframes text-shadow-glitch { - 0% { - text-shadow: - 1px 0 0 rgba(255,0,255,0.5), - -1px 0 0 rgba(0,255,255,0.5); - } - 10% { - text-shadow: - -1px 0 0 rgba(255,0,255,0.5), - 1px 0 0 rgba(0,255,255,0.5); - } - 11%, 100% { - text-shadow: none; - } -} - -.controls { - margin-top: 30px; - display: flex; - align-items: center; - gap: 20px; -} - -#new-literature-btn { - background-color: #ff00ff; - color: #fff; - border: none; - padding: 12px 25px; - font-size: 1em; - cursor: pointer; - border-radius: 5px; - text-transform: uppercase; - font-weight: bold; - transition: transform 0.2s, box-shadow 0.2s; - box-shadow: 0 0 10px #ff00ff, 0 0 20px #ff00ff; -} - -#new-literature-btn:hover { - transform: scale(1.05); - box-shadow: 0 0 15px #ff00ff, 0 0 30px #ff00ff; -} - -#new-literature-btn:active { - transform: scale(0.95); -} - -/* Animation Toggle Switch */ -.switch-container { - display: flex; - align-items: center; - gap: 10px; - color: #aaa; -} - -.switch { - position: relative; - display: inline-block; - width: 50px; - height: 24px; -} - -.switch input { - opacity: 0; - width: 0; - height: 0; -} - -.slider { - position: absolute; - cursor: pointer; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: #ccc; - transition: .4s; -} - -.slider:before { - position: absolute; - content: ""; - height: 16px; - width: 16px; - left: 4px; - bottom: 4px; - background-color: white; - transition: .4s; -} - -input:checked + .slider { - background-color: #ff00ff; -} - -input:checked + .slider:before { - transform: translateX(26px); -} - -.slider.round { - border-radius: 34px; -} - -.slider.round:before { - border-radius: 50%; -} - -/* Glitch Overlay & Animations */ -#glitch-overlay { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: -1; - pointer-events: none; -} - -.body-animated #glitch-overlay { - animation: color-shift 15s steps(1, end) infinite; -} - -@keyframes color-shift { - 0%, 100% { background: transparent; } - 10% { background: rgba(255, 0, 0, 0.05); } - 10.1% { background: transparent; } - 20% { background: rgba(0, 255, 0, 0.05); } - 20.1% { background: transparent; } - 30% { background: rgba(0, 0, 255, 0.05); } - 30.1% { background: transparent; } -} - -.flicker-block { - position: absolute; - background: rgba(255, 255, 255, 0.1); - opacity: 0; -} - -.body-animated .flicker-block { - animation: flicker 3s infinite; -} - -@keyframes flicker { - 0%, 100% { opacity: 0; } - 50% { opacity: 1; } -} - -/* Responsive Design */ -@media (max-width: 768px) { - .content-card { - padding: 20px; - } - #literature-text { - font-size: 1em; - } - .controls { - flex-direction: column; - } -} \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机发病文学/index.html b/frontend/60sapi/娱乐消遣/随机发病文学/index.html deleted file mode 100755 index 5af98657..00000000 --- a/frontend/60sapi/娱乐消遣/随机发病文学/index.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - 随机发病文学 - - - - -
-
-
- -
-
-

正在加载发病文学...

-
- -
- -
- - -
-
-
- - - - \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机发病文学/js/script.js b/frontend/60sapi/娱乐消遣/随机发病文学/js/script.js deleted file mode 100755 index f4901b06..00000000 --- a/frontend/60sapi/娱乐消遣/随机发病文学/js/script.js +++ /dev/null @@ -1,147 +0,0 @@ -document.addEventListener('DOMContentLoaded', () => { - const literatureTextElem = document.getElementById('literature-text'); - const newLiteratureBtn = document.getElementById('new-literature-btn'); - const animationToggle = document.getElementById('animation-toggle'); - const bgContainer = document.getElementById('bg-container'); - const body = document.body; - - const apiEndpoints = [ - 'https://60s.api.shumengya.top/v2/fabing', - // Add fallback APIs here if available - ]; - - let currentApiIndex = 0; - - async function fetchLiterature() { - literatureTextElem.textContent = '正在卖力发疯中...'; - literatureTextElem.style.opacity = '0.5'; - - try { - const response = await fetch(apiEndpoints[currentApiIndex]); - if (!response.ok) { - throw new Error('Network response was not ok'); - } - const data = await response.json(); - if (data.code === 200) { - literatureTextElem.textContent = data.data.saying; - } else { - throw new Error('API returned an error'); - } - } catch (error) { - console.error('Fetch error:', error); - currentApiIndex = (currentApiIndex + 1) % apiEndpoints.length; - if (currentApiIndex !== 0) { - fetchLiterature(); // Retry with the next API - } else { - literatureTextElem.textContent = '疯不起来了,请稍后再试。'; - } - } finally { - literatureTextElem.style.opacity = '1'; - } - } - - function createFloatingEmojis() { - const existingEmojis = bgContainer.querySelectorAll('.floating-emoji'); - existingEmojis.forEach(e => e.remove()); - - const emojis = ['🤯', '😵', '🤪', '🥴', '🤡', '👹', '👻', '💀', '💥', '🔥', '🌪️', '😵‍💫']; - const animationNames = ['float-top-to-bottom', 'float-bottom-to-top', 'float-left-to-right', 'float-right-to-left']; - const emojiCount = 25; - - for (let i = 0; i < emojiCount; i++) { - const emojiEl = document.createElement('div'); - emojiEl.className = 'floating-emoji'; - emojiEl.textContent = emojis[Math.floor(Math.random() * emojis.length)]; - - const animationName = animationNames[Math.floor(Math.random() * animationNames.length)]; - emojiEl.style.animationName = animationName; - emojiEl.style.animationDuration = `${Math.random() * 10 + 15}s`; // 15-25 seconds - emojiEl.style.animationDelay = `${Math.random() * 20}s`; - emojiEl.style.fontSize = `${Math.random() * 20 + 20}px`; - - // Set initial position based on animation direction - if (animationName.includes('top') || animationName.includes('bottom')) { // Vertical movement - emojiEl.style.left = `${Math.random() * 100}vw`; - } else { // Horizontal movement - emojiEl.style.top = `${Math.random() * 100}vh`; - } - - bgContainer.appendChild(emojiEl); - } - } - - function createFragments() { - const existingFragments = bgContainer.querySelectorAll('.text-fragment'); - existingFragments.forEach(f => f.remove()); - - const fragments = ['我', '疯', '了', '?', '!', '…', '救命', '为什么', '好烦', '啊啊啊']; - for (let i = 0; i < 20; i++) { - const frag = document.createElement('div'); - frag.className = 'text-fragment'; - frag.textContent = fragments[Math.floor(Math.random() * fragments.length)]; - frag.style.top = `${Math.random() * 100}%`; - frag.style.left = `${Math.random() * 100}%`; - frag.style.animationDelay = `${Math.random() * 15}s`; - frag.style.fontSize = `${Math.random() * 12 + 12}px`; - bgContainer.appendChild(frag); - } - } - - function createCracks() { - for (let i = 0; i < 2; i++) { - const crack = document.createElement('div'); - crack.className = 'screen-crack'; - crack.style.top = `${Math.random() * 80}%`; - crack.style.left = `${Math.random() * 80}%`; - crack.style.transform = `rotate(${Math.random() * 360}deg)`; - crack.style.animationDelay = `${Math.random() * 25}s`; - bgContainer.appendChild(crack); - } - } - - function createFlickerBlocks() { - const glitchOverlay = document.getElementById('glitch-overlay'); - for (let i = 0; i < 3; i++) { - const block = document.createElement('div'); - block.className = 'flicker-block'; - block.style.width = `${Math.random() * 100 + 50}px`; - block.style.height = `${Math.random() * 100 + 50}px`; - block.style.top = `${Math.random() * 90}%`; - block.style.left = `${Math.random() * 90}%`; - block.style.animationDuration = `${Math.random() * 2 + 2}s`; - block.style.animationDelay = `${Math.random() * 3}s`; - glitchOverlay.appendChild(block); - } - } - - function toggleAnimations() { - if (animationToggle.checked) { - body.classList.add('body-animated'); - } else { - body.classList.remove('body-animated'); - } - } - - document.addEventListener('mousemove', (e) => { - if (!animationToggle.checked) return; - const x = (window.innerWidth / 2) - e.pageX; - const y = (window.innerHeight / 2) - e.pageY; - bgContainer.style.transform = `translateX(${x / 50}px) translateY(${y / 50}px)`; - }); - - newLiteratureBtn.addEventListener('click', fetchLiterature); - animationToggle.addEventListener('change', toggleAnimations); - - // Initial setup - createFloatingEmojis(); - createFragments(); - createCracks(); - createFlickerBlocks(); - toggleAnimations(); - fetchLiterature(); - - window.addEventListener('resize', () => { - createFloatingEmojis(); - createFragments(); - }); -}); \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机发病文学/接口集合.json b/frontend/60sapi/娱乐消遣/随机发病文学/接口集合.json deleted file mode 100755 index 37dc3082..00000000 --- a/frontend/60sapi/娱乐消遣/随机发病文学/接口集合.json +++ /dev/null @@ -1 +0,0 @@ -["https://60s.api.shumengya.top"] \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机发病文学/返回接口.json b/frontend/60sapi/娱乐消遣/随机发病文学/返回接口.json deleted file mode 100755 index 4a6d180e..00000000 --- a/frontend/60sapi/娱乐消遣/随机发病文学/返回接口.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "code": 200, - "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", - "data": { - "index": 347, - "duanzi": "我不想读书,主要是因为家里牛啊,猪啊羊啊都没人喂。" - } -} \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机唱歌音频/css/style.css b/frontend/60sapi/娱乐消遣/随机唱歌音频/css/style.css deleted file mode 100755 index c6b6f0d6..00000000 --- a/frontend/60sapi/娱乐消遣/随机唱歌音频/css/style.css +++ /dev/null @@ -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; - } -} \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机唱歌音频/index.html b/frontend/60sapi/娱乐消遣/随机唱歌音频/index.html deleted file mode 100755 index 3134b76d..00000000 --- a/frontend/60sapi/娱乐消遣/随机唱歌音频/index.html +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - 随机唱歌音频 - 60s API 集合 - - - - - -
-
-

- 🎵 随机唱歌音频 -

-

数据来自官方/权威源头,以确保稳定与实时 · 支持本地数据回退

-
- - -
-
-

正在加载中,请稍候…

-
- - - - -
- -
- 用户头像 - -
- - -
-
-
-
-
-
-
- - -
- -
- -
- ❤ 喜欢:- - · ⏱ 时长:--:-- - · 🗓 发布:- - · 🔗 查看原帖 -
-
-
-
-
- - - - \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机唱歌音频/js/script.js b/frontend/60sapi/娱乐消遣/随机唱歌音频/js/script.js deleted file mode 100755 index a6ec7c07..00000000 --- a/frontend/60sapi/娱乐消遣/随机唱歌音频/js/script.js +++ /dev/null @@ -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.api.shumengya.top/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(); - }); -})(); \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机唱歌音频/接口集合.json b/frontend/60sapi/娱乐消遣/随机唱歌音频/接口集合.json deleted file mode 100755 index 547b2771..00000000 --- a/frontend/60sapi/娱乐消遣/随机唱歌音频/接口集合.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "https://60s.api.shumengya.top" -] diff --git a/frontend/60sapi/娱乐消遣/随机唱歌音频/返回接口.json b/frontend/60sapi/娱乐消遣/随机唱歌音频/返回接口.json deleted file mode 100755 index d364f524..00000000 --- a/frontend/60sapi/娱乐消遣/随机唱歌音频/返回接口.json +++ /dev/null @@ -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 - } - } -} \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机搞笑段子/css/background.css b/frontend/60sapi/娱乐消遣/随机搞笑段子/css/background.css deleted file mode 100755 index 7f1aa01c..00000000 --- a/frontend/60sapi/娱乐消遣/随机搞笑段子/css/background.css +++ /dev/null @@ -1,36 +0,0 @@ -body { - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; - margin: 0; - min-height: 100vh; - overflow-x: hidden; - transition: background 0.5s ease; -} - -/* Hand-drawn Comic Theme Background - NEW VIBRANT VERSION */ -body.theme-comic { - background: linear-gradient(-45deg, #ff7e5f, #feb47b, #ffcc80, #ffecb3); - background-size: 400% 400%; - animation: gradientBG 15s ease infinite; -} - -@keyframes gradientBG { - 0% { - background-position: 0% 50%; - } - 50% { - background-position: 100% 50%; - } - 100% { - background-position: 0% 50%; - } -} - -/* Placeholder for Emoji Theme Background */ -body.theme-emoji { - background-color: #fffde7; -} - -/* Placeholder for Retro TV Theme Background */ -body.theme-retro { - background-color: #3d2b1f; -} \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机搞笑段子/css/style.css b/frontend/60sapi/娱乐消遣/随机搞笑段子/css/style.css deleted file mode 100755 index 5dccdee4..00000000 --- a/frontend/60sapi/娱乐消遣/随机搞笑段子/css/style.css +++ /dev/null @@ -1,199 +0,0 @@ -@import url('https://fonts.googleapis.com/css2?family=Zhi+Mang+Xing&display=swap'); - -/* --- General & Theme Switcher --- */ -.container { - max-width: 600px; - margin: 0 auto; - padding: 20px; - text-align: center; -} - -.theme-switcher { - position: fixed; - top: 15px; - right: 15px; - display: flex; - gap: 5px; - background: rgba(255, 255, 255, 0.8); - padding: 5px; - border-radius: 20px; - box-shadow: 0 2px 10px rgba(0,0,0,0.1); - z-index: 100; -} - -.theme-icon { - width: 30px; - height: 30px; - border-radius: 50%; - display: flex; - justify-content: center; - align-items: center; - cursor: pointer; - transition: all 0.2s ease; - border: 2px solid transparent; -} -.theme-icon.active { - border-color: #ff7043; - transform: scale(1.1); -} - -/* --- Comic Theme Styles --- */ -.theme-comic header h1 { - font-family: 'Zhi Mang Xing', cursive; - font-size: 4em; - color: #d84315; /* Deep Orange */ - text-shadow: 2px 2px 0 #fff; - margin: 0.2em 0; -} - -.theme-comic .divider { - height: 3px; - background: linear-gradient(90deg, #ffca28, #ff7043, #29b6f6, #66bb6a); - border-radius: 3px; - margin: 20px auto; - width: 80%; -} - -.theme-comic .joke-card { - background: rgba(255, 255, 255, 0.85); /* White with transparency */ - backdrop-filter: blur(5px); - border-radius: 15px; - padding: 40px; - min-height: 200px; - box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15); - display: flex; - justify-content: center; - align-items: center; - position: relative; - margin-bottom: 20px; - transform: rotate(-1deg); - transition: transform 0.2s ease; -} -.theme-comic .joke-card:hover { - transform: rotate(1deg) scale(1.02); -} - -.theme-comic .joke-text { - font-family: 'Zhi Mang Xing', cursive; - font-size: 2em; - line-height: 1.6; - color: #5d4037; -} - -.theme-comic .new-joke-btn { - background: #1e88e5; /* Vibrant Blue */ - color: white; - font-family: 'Zhi Mang Xing', cursive; - font-size: 2.5em; - border: none; - border-radius: 50px; - padding: 10px 30px; - cursor: pointer; - box-shadow: 0 5px 0 #1565c0; /* Darker Blue */ - transition: all 0.1s ease-in-out; -} -.theme-comic .new-joke-btn:active { - transform: translateY(5px); - box-shadow: none; -} - -/* --- Loading Animation --- */ -.loading-container { display: none; } -.loading-container.visible { display: block; } -.loading-anim { - height: 60px; - width: 80px; - margin: 0 auto 10px; -} -.book { - transform-style: preserve-3d; - transform: rotateY(-30deg); - animation: flip 3s infinite; -} -.book, .book-page { - width: 40px; - height: 55px; - position: absolute; - left: 50%; - top: 50%; - margin-left: -20px; - margin-top: -27.5px; -} -.book-page { - background: #ffca28; - border: 1px solid #ff7043; - border-radius: 3px; - transform-origin: left; -} -.book-page:nth-child(1) { animation: flip-page 3s infinite; } -.book-page:nth-child(2) { animation: flip-page 3s -1s infinite; } -.book-page:nth-child(3) { animation: flip-page 3s -2s infinite; } - -@keyframes flip { 50% { transform: rotateY(30deg); } } -@keyframes flip-page { 30%, 100% { transform: rotateY(180deg); } } - -/* --- Feedback Buttons & Animations --- */ -.feedback-buttons { - display: flex; - justify-content: center; - gap: 15px; - margin-bottom: 30px; -} -.feedback-btn { - background: none; - border: none; - font-size: 2em; - cursor: pointer; - transition: transform 0.2s ease; -} -.feedback-btn:hover { transform: scale(1.2); } - -#animation-container { - position: fixed; - top: 0; left: 0; width: 100%; height: 100%; - pointer-events: none; z-index: 999; -} -.confetti, .snowflake { - position: absolute; - animation-timing-function: linear; - animation-iteration-count: infinite; -} -.confetti { - width: 10px; height: 10px; - animation-name: fall; -} -.snowflake { - font-size: 20px; color: #fff; - animation-name: fall; -} -@keyframes fall { - from { transform: translateY(-10vh) rotate(0deg); } - to { transform: translateY(110vh) rotate(360deg); } -} - -.joke-card.absurd { - animation: absurd-flash 0.5s 2; -} -@keyframes absurd-flash { - 0%, 100% { border: 2px solid transparent; } - 50% { border: 5px solid red; } -} - -/* --- General Joke Text Visibility --- */ -.joke-text { - opacity: 0; - transform: scale(0.9); - transition: opacity 0.4s ease, transform 0.4s ease; -} -.joke-text.visible { - opacity: 1; - transform: scale(1); -} - -/* --- Responsive --- */ -@media (max-width: 600px) { - .theme-comic header h1 { font-size: 3em; } - .theme-comic .joke-card { padding: 25px; transform: rotate(0); } - .theme-comic .joke-card:hover { transform: rotate(0); } - .theme-comic .joke-text { font-size: 1.5em; } -} \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机搞笑段子/index.html b/frontend/60sapi/娱乐消遣/随机搞笑段子/index.html deleted file mode 100755 index e443b252..00000000 --- a/frontend/60sapi/娱乐消遣/随机搞笑段子/index.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - 段子游乐场 - - - - - -
-
✏️
-
😂
-
📺
-
- -
-
-

段子游乐场

-
-
- -
-
-
-
-
-
-
-
-
-
-

段子菌正在翻笑话库...

-
-

-
- - - - -
-
- - -
- - - - - - \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机搞笑段子/js/script.js b/frontend/60sapi/娱乐消遣/随机搞笑段子/js/script.js deleted file mode 100755 index 5fce3956..00000000 --- a/frontend/60sapi/娱乐消遣/随机搞笑段子/js/script.js +++ /dev/null @@ -1,122 +0,0 @@ -document.addEventListener('DOMContentLoaded', () => { - // Elements - const body = document.body; - const jokeTextElem = document.getElementById('joke-text'); - const newJokeBtn = document.getElementById('new-joke-btn'); - const loadingContainer = document.querySelector('.loading-container'); - const animationContainer = document.getElementById('animation-container'); - const jokeCard = document.getElementById('joke-card'); - - // API - const apiBaseUrls = ["https://60s.api.shumengya.top"]; - const apiPath = "/v2/duanzi"; - let currentApiIndex = 0; - - // --- Core Functions --- - const showLoading = (isLoading) => { - loadingContainer.classList.toggle('visible', isLoading); - if (isLoading) jokeTextElem.classList.remove('visible'); - }; - - const displayJoke = (joke) => { - jokeTextElem.textContent = joke; - showLoading(false); - setTimeout(() => jokeTextElem.classList.add('visible'), 50); - }; - - const fetchJoke = async () => { - showLoading(true); - try { - const url = apiBaseUrls[currentApiIndex] + apiPath; - const response = await fetch(url, { timeout: 5000 }); - if (!response.ok) throw new Error('Network response was not ok'); - - const data = await response.json(); - if (data.code === 200 && data.data && data.data.duanzi) { - displayJoke(data.data.duanzi); - } else { - throw new Error('Invalid data format'); - } - } catch (error) { - console.error(`API error with ${apiBaseUrls[currentApiIndex]}:`, error); - currentApiIndex = (currentApiIndex + 1) % apiBaseUrls.length; - if (currentApiIndex !== 0) { - fetchJoke(); // Try next API - } else { - displayJoke('段子菌迷路了!点击‘再来一个’让它重新找路~'); - } - } - }; - - // --- Theme Switcher --- - const themeSwitcher = document.querySelector('.theme-switcher'); - themeSwitcher.addEventListener('click', (e) => { - if (e.target.classList.contains('theme-icon')) { - const theme = e.target.dataset.theme; - body.className = theme; // Set body class to the selected theme - - // Update active icon - themeSwitcher.querySelectorAll('.theme-icon').forEach(icon => icon.classList.remove('active')); - e.target.classList.add('active'); - - alert(`主题已切换!部分主题(如表情包、复古电视)将在后续阶段实现。`); - } - }); - // Set initial active theme icon - themeSwitcher.querySelector(`[data-theme="${body.className}"]`).classList.add('active'); - - - // --- Feedback Buttons & Animations --- - const btnLol = document.getElementById('btn-lol'); - const btnCold = document.getElementById('btn-cold'); - const btnSeen = document.getElementById('btn-seen'); - const btnAbsurd = document.getElementById('btn-absurd'); - const soundLol = document.getElementById('sound-lol'); - const soundCold = document.getElementById('sound-cold'); - - btnLol.addEventListener('click', () => { - soundLol.play(); - createParticles(20, 'confetti'); - }); - - btnCold.addEventListener('click', () => { - soundCold.play(); - createParticles(15, 'snowflake'); - }); - - btnSeen.addEventListener('click', () => { - displayJoke("原来你也听过!那再给你换个新鲜的~"); - setTimeout(fetchJoke, 1500); - }); - - btnAbsurd.addEventListener('click', () => { - jokeCard.classList.add('absurd'); - setTimeout(() => jokeCard.classList.remove('absurd'), 1000); - }); - - function createParticles(count, type) { - animationContainer.innerHTML = ''; // Clear previous - const colors = ['#ffca28', '#ff7043', '#29b6f6', '#66bb6a']; - for (let i = 0; i < count; i++) { - const particle = document.createElement('div'); - particle.classList.add(type); - if (type === 'confetti') { - particle.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)]; - } else { - particle.textContent = '❄️'; - } - particle.style.left = `${Math.random() * 100}vw`; - const duration = Math.random() * 3 + 2; // 2-5 seconds - const delay = Math.random() * -duration; // Start at different times - particle.style.animationDuration = `${duration}s`; - particle.style.animationDelay = `${delay}s`; - animationContainer.appendChild(particle); - } - } - - // --- Event Listeners --- - newJokeBtn.addEventListener('click', fetchJoke); - - // --- Initial Load --- - fetchJoke(); -}); \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机搞笑段子/接口集合.json b/frontend/60sapi/娱乐消遣/随机搞笑段子/接口集合.json deleted file mode 100755 index 37dc3082..00000000 --- a/frontend/60sapi/娱乐消遣/随机搞笑段子/接口集合.json +++ /dev/null @@ -1 +0,0 @@ -["https://60s.api.shumengya.top"] \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机搞笑段子/返回接口.json b/frontend/60sapi/娱乐消遣/随机搞笑段子/返回接口.json deleted file mode 100755 index 4a6d180e..00000000 --- a/frontend/60sapi/娱乐消遣/随机搞笑段子/返回接口.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "code": 200, - "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", - "data": { - "index": 347, - "duanzi": "我不想读书,主要是因为家里牛啊,猪啊羊啊都没人喂。" - } -} \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机运势/css/background.css b/frontend/60sapi/娱乐消遣/随机运势/css/background.css deleted file mode 100755 index d18a8699..00000000 --- a/frontend/60sapi/娱乐消遣/随机运势/css/background.css +++ /dev/null @@ -1,26 +0,0 @@ -body { - background: linear-gradient(-45deg, #0a021a, #2a0d3f, #4a1a6c, #7b2f8f); - background-size: 400% 400%; - animation: gradientBG 20s ease infinite; - color: #ffffff; - font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; - margin: 0; - padding: 0; - display: flex; - justify-content: center; - align-items: center; - min-height: 100vh; - overflow-x: hidden; -} - -@keyframes gradientBG { - 0% { - background-position: 0% 50%; - } - 50% { - background-position: 100% 50%; - } - 100% { - background-position: 0% 50%; - } -} \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机运势/css/style.css b/frontend/60sapi/娱乐消遣/随机运势/css/style.css deleted file mode 100755 index 7792be02..00000000 --- a/frontend/60sapi/娱乐消遣/随机运势/css/style.css +++ /dev/null @@ -1,342 +0,0 @@ -.container { - text-align: center; - padding: 20px; - max-width: 600px; - width: 100%; - box-sizing: border-box; -} - -header h1 { - font-size: 2.8em; - color: #f0e6ff; - text-shadow: 0 0 10px #d1a9ff, 0 0 20px #d1a9ff; - margin-bottom: 0.2em; -} - -header p { - font-size: 1.2em; - color: #e0c8ff; - margin-bottom: 40px; -} - -.crystal-ball-container { - perspective: 1000px; - margin-bottom: 40px; -} - -.crystal-ball { - width: 200px; - height: 200px; - background: radial-gradient(circle at 30% 30%, rgba(255, 255, 255, 0.6), rgba(200, 180, 255, 0.1)); - border-radius: 50%; - margin: 0 auto; - position: relative; - box-shadow: 0 0 30px #c390ff, 0 0 60px #a060e0, inset 0 0 20px rgba(255, 220, 255, 0.3); - animation: float 6s ease-in-out infinite; - transform-style: preserve-3d; -} - -.reflection { - width: 80px; - height: 40px; - background: rgba(255, 255, 255, 0.3); - border-radius: 50%; - position: absolute; - top: 20px; - left: 40px; - transform: rotate(-30deg); - filter: blur(5px); -} - -.swirl { - position: absolute; - top: 50%; - left: 50%; - width: 120%; - height: 120%; - background: linear-gradient(45deg, rgba(255, 192, 203, 0.1), rgba(128, 0, 128, 0.2)); - border-radius: 50%; - animation: swirl 10s linear infinite; - transform: translate(-50%, -50%); -} - -@keyframes float { - 0%, 100% { transform: translateY(0); } - 50% { transform: translateY(-20px); } -} - -@keyframes swirl { - from { transform: translate(-50%, -50%) rotate(0deg); } - to { transform: translate(-50%, -50%) rotate(360deg); } -} - -.fortune-card { - background: rgba(255, 255, 255, 0.05); - border-radius: 15px; - padding: 30px; - margin-bottom: 30px; - min-height: 120px; - display: flex; - justify-content: center; - align-items: center; - backdrop-filter: blur(10px); - border: 1px solid rgba(255, 255, 255, 0.1); - box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37); - transition: opacity 0.5s ease-in-out; -} - -.fortune-content { - opacity: 0; - transition: opacity 0.5s ease-in-out; -} - -.fortune-content.visible { - opacity: 1; -} - -#luck-desc { - font-size: 2em; - color: #ffc0cb; - margin: 0 0 10px; -} - -#luck-tip { - font-size: 1.1em; - color: #e0e0e0; - margin: 0; - padding-bottom: 20px; /* Add some space before the new details */ -} - -.fortune-details { - display: flex; - justify-content: space-around; - margin-top: 20px; - padding-top: 20px; - border-top: 1px solid rgba(255, 255, 255, 0.2); -} - -.detail-item { - text-align: center; -} - -.detail-item h3 { - font-size: 0.9em; - color: #ffc0cb; - margin: 0 0 5px; - font-weight: normal; -} - -.detail-item p { - font-size: 1.2em; - margin: 0; - font-weight: bold; -} - -#lucky-color { - display: inline-block; - width: 24px; - height: 24px; - border-radius: 50%; - border: 2px solid white; - box-shadow: 0 0 5px rgba(0, 0, 0, 0.5); - /* Remove the text content */ - font-size: 0; -} - -/* Tarot Card Styles */ -.tarot-container { - margin-top: 40px; - margin-bottom: 40px; -} - -.tarot-container h2 { - font-size: 1.5em; - color: #f0e6ff; - text-shadow: 0 0 8px #d1a9ff; - margin-bottom: 20px; -} - -.tarot-card-container { - width: 180px; - height: 280px; - perspective: 1000px; - margin: 0 auto; - cursor: pointer; -} - -.tarot-card-inner { - position: relative; - width: 100%; - height: 100%; - transition: transform 0.8s; - transform-style: preserve-3d; -} - -.tarot-card-container.flipped .tarot-card-inner { - transform: rotateY(180deg); -} - -.tarot-card-front, -.tarot-card-back { - position: absolute; - width: 100%; - height: 100%; - -webkit-backface-visibility: hidden; - backface-visibility: hidden; - border-radius: 10px; - box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4); -} - -.tarot-card-back { - background: linear-gradient(135deg, #4a1a6c, #2a0d3f); - border: 2px solid #d1a9ff; - display: flex; - justify-content: center; - align-items: center; - font-size: 3em; - color: #d1a9ff; -} - -.tarot-card-back::after { - content: '✧'; /* A simple star symbol */ - text-shadow: 0 0 10px #f0e6ff; -} - -.tarot-card-front { - background: linear-gradient(135deg, #3e165b, #592883); - border: 2px solid #d1a9ff; - color: white; - transform: rotateY(180deg); - padding: 20px; - box-sizing: border-box; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; -} - -#tarot-name { - font-size: 1.4em; - color: #ffc0cb; - margin: 0 0 10px; -} - -#tarot-interpretation { - font-size: 0.9em; - text-align: center; - margin: 0; -} - -/* Side Decorations */ -.side-decor { - position: fixed; - top: 0; - bottom: 0; - width: 15vw; - height: 100vh; - pointer-events: none; - z-index: 0; -} - -.left-decor { - left: 0; -} - -.right-decor { - right: 0; -} - -.decor-symbol { - position: absolute; - color: rgba(209, 169, 255, 0.5); - text-shadow: 0 0 10px rgba(240, 230, 255, 0.7); - animation: floatSymbol 20s infinite ease-in-out; -} - -@keyframes floatSymbol { - 0%, 100% { - transform: translateY(0) rotate(0deg); - opacity: 0; - } - 25%, 75% { - opacity: 0.8; - } - 50% { - transform: translateY(-20vh) rotate(180deg); - opacity: 0.3; - } -} - -#get-fortune-btn { - background: linear-gradient(45deg, #da70d6, #8a2be2); - color: white; - border: none; - border-radius: 50px; - padding: 15px 30px; - font-size: 1.1em; - cursor: pointer; - transition: transform 0.2s, box-shadow 0.2s; - box-shadow: 0 0 15px #c390ff; -} - -#get-fortune-btn:hover { - transform: scale(1.05); - box-shadow: 0 0 25px #d1a9ff; -} - -#get-fortune-btn:active { - transform: scale(0.98); -} - -.loading-spinner { - border: 4px solid rgba(255, 255, 255, 0.2); - border-left-color: #ffc0cb; - border-radius: 50%; - width: 40px; - height: 40px; - animation: spin 1s linear infinite; - display: none; /* Hidden by default */ -} - -.loading-spinner.visible { - display: block; -} - -@keyframes spin { - to { transform: rotate(360deg); } -} - -footer { - margin-top: 40px; - color: rgba(255, 255, 255, 0.6); -} - -/* Responsive Design */ -@media (max-width: 768px) { - header h1 { - font-size: 2.2em; - } - .crystal-ball { - width: 150px; - height: 150px; - } - .fortune-card { - padding: 20px; - } - .fortune-details { - flex-direction: column; - gap: 15px; - } - - .tarot-card-container { - width: 150px; - height: 233px; - } -} - -/* Hide side decor on smaller screens */ -@media (max-width: 1200px) { - .side-decor { - display: none; - } -} \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机运势/index.html b/frontend/60sapi/娱乐消遣/随机运势/index.html deleted file mode 100755 index 4214eeb4..00000000 --- a/frontend/60sapi/娱乐消遣/随机运势/index.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - 水晶球占卜 - - - - -
-
-
-

水晶球占卜

-

洞察你今日的运势

-
-
-
-
-
-
-
-
-
-
-
-

-

-
-
-

今日咒语

-

-
-
-

幸运色

-

-
-
-

幸运数字

-

-
-
-
-
- - -
-

每日塔罗指引

-
-
-
- -
-
-

-

-
-
-
-
- - -
-
-

仅供娱乐,祝您好运

-
-
-
- - - \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机运势/js/script.js b/frontend/60sapi/娱乐消遣/随机运势/js/script.js deleted file mode 100755 index 596b807a..00000000 --- a/frontend/60sapi/娱乐消遣/随机运势/js/script.js +++ /dev/null @@ -1,170 +0,0 @@ -document.addEventListener('DOMContentLoaded', () => { - const getFortuneBtn = document.getElementById('get-fortune-btn'); - const fortuneCard = document.getElementById('fortune-card'); - const fortuneContent = fortuneCard.querySelector('.fortune-content'); - const luckDescElem = document.getElementById('luck-desc'); - const luckTipElem = document.getElementById('luck-tip'); - const fortuneSummaryElem = document.getElementById('fortune-summary'); - const luckyColorElem = document.getElementById('lucky-color'); - const luckyNumberElem = document.getElementById('lucky-number'); - const loadingSpinner = fortuneCard.querySelector('.loading-spinner'); - const tarotCardContainer = document.getElementById('tarot-card'); - const tarotNameElem = document.getElementById('tarot-name'); - const tarotInterpretationElem = document.getElementById('tarot-interpretation'); - - const apiBaseUrls = [ - "https://60s.api.shumengya.top", - ]; - const apiPath = "/v2/luck"; - - const mantras = [ - "顺其自然,皆是美好。", - "相信直觉,它知道方向。", - "每一次呼吸都是新的开始。", - "心怀感恩,好运自来。", - "拥抱变化,发现惊喜。", - "你的能量,超乎想象。", - "保持微笑,宇宙会回应你。" - ]; - - const tarotDeck = [ - { name: "愚者", interpretation: "新的开始,无限的潜力,天真和自由。勇敢地迈出第一步。" }, - { name: "魔术师", interpretation: "创造力,意志力,显化。你拥有实现目标所需的一切资源。" }, - { name: "女祭司", interpretation: "直觉,潜意识,神秘。倾听你内心的声音,智慧在你之内。" }, - { name: "皇后", interpretation: "丰饶,母性,创造。享受生活的美好,与自然和谐相处。" }, - { name: "皇帝", interpretation: "权威,结构,控制。建立秩序和纪律,掌控你的生活。" }, - { name: "教皇", interpretation: "传统,信仰,灵性指导。寻求智慧和知识,遵循传统。" }, - { name: "恋人", interpretation: "爱,和谐,选择。做出与你内心价值观一致的决定。" }, - { name: "战车", interpretation: "胜利,决心,控制。以坚定的意志力克服障碍,勇往直前。" }, - { name: "力量", interpretation: "勇气,内在力量,同情。用温柔和耐心驯服内心的野兽。" }, - { name: "隐士", interpretation: "内省,孤独,寻求真理。花时间独处,向内寻求答案。" }, - { name: "命运之轮", interpretation: "变化,命运,转折点。生活总在变化,顺应潮流。" }, - { name: "正义", interpretation: "公平,真理,因果。为你的行为负责,寻求平衡。" }, - { name: "倒吊人", interpretation: "新的视角,顺从,牺牲。放手,从不同的角度看问题。" }, - { name: "死神", interpretation: "结束,转变,新生。一个周期的结束是另一个周期的开始。" }, - { name: "节制", interpretation: "平衡,和谐,耐心。融合对立的力量,找到中间道路。" }, - { name: "恶魔", interpretation: "束缚,物质主义,诱惑。认识到你的束缚,并寻求解放。" }, - { name: "塔", interpretation: "突变,启示,解放。旧的结构正在崩塌,为新的结构让路。" }, - { name: "星星", interpretation: "希望,灵感,平静。在黑暗之后,总有希望的曙光。" }, - { name: "月亮", interpretation: "幻觉,恐惧,潜意识。面对你的恐惧,相信你的直觉。" }, - { name: "太阳", interpretation: "成功,喜悦,活力。拥抱光明,享受生活的乐趣。" }, - { name: "审判", interpretation: "觉醒,重生,评估。一个反思和更新的时刻。" }, - { name: "世界", interpretation: "完成,整合,成就。一个旅程的成功结束,庆祝你的成就。" } - ]; - - let currentApiIndex = 0; - - const showLoading = (isLoading) => { - if (isLoading) { - fortuneContent.classList.remove('visible'); - loadingSpinner.classList.add('visible'); - } else { - loadingSpinner.classList.remove('visible'); - setTimeout(() => { - fortuneContent.classList.add('visible'); - }, 100); - } - }; - - const fetchFortune = async () => { - showLoading(true); - tarotCardContainer.classList.remove('flipped'); // Reset card on new fetch - - try { - const url = apiBaseUrls[currentApiIndex] + apiPath; - const response = await fetch(url, { timeout: 5000 }); - if (!response.ok) { - throw new Error('Network response was not ok'); - } - const data = await response.json(); - - if (data.code === 200 && data.data) { - updateFortune(data.data); - drawTarotCard(); // Draw a tarot card on success - } else { - throw new Error('Invalid data format'); - } - } catch (error) { - console.error(`API error with ${apiBaseUrls[currentApiIndex]}:`, error); - currentApiIndex = (currentApiIndex + 1) % apiBaseUrls.length; - if (currentApiIndex !== 0) { - fetchFortune(); // Try next API - } else { - displayError(); - } - } - }; - - const updateFortune = (data) => { - luckDescElem.textContent = data.luck_desc || '运势'; - luckTipElem.textContent = data.luck_tip || '今日运势平平,保持好心情。'; - - // Generate and display additional details - fortuneSummaryElem.textContent = mantras[Math.floor(Math.random() * mantras.length)]; - luckyColorElem.style.backgroundColor = `#${Math.floor(Math.random()*16777215).toString(16).padStart(6, '0')}`; - luckyNumberElem.textContent = Math.floor(Math.random() * 100); - - showLoading(false); - }; - - const displayError = () => { - luckDescElem.textContent = '占卜失败'; - luckTipElem.textContent = '无法连接到星辰之力,请稍后再试。'; - fortuneSummaryElem.textContent = '---'; - luckyColorElem.style.backgroundColor = 'transparent'; - luckyNumberElem.textContent = '-'; - showLoading(false); - tarotNameElem.textContent = '指引中断'; - tarotInterpretationElem.textContent = '星辰之力暂时无法连接。'; - tarotCardContainer.classList.add('flipped'); // Show error on card - }; - - const drawTarotCard = () => { - const card = tarotDeck[Math.floor(Math.random() * tarotDeck.length)]; - tarotNameElem.textContent = card.name; - tarotInterpretationElem.textContent = card.interpretation; - - // Flip the card after a short delay to allow the main content to appear - setTimeout(() => { - tarotCardContainer.classList.add('flipped'); - }, 500); - }; - - const createSideDecorations = () => { - const leftContainer = document.querySelector('.left-decor'); - const rightContainer = document.querySelector('.right-decor'); - if (!leftContainer || !rightContainer) return; - - const symbols = ['✧', '✦', '☾', '✶', '✵', '✩', '✨']; - const symbolCount = 15; // Number of symbols per side - - const createSymbols = (container) => { - for (let i = 0; i < symbolCount; i++) { - const symbol = document.createElement('span'); - symbol.classList.add('decor-symbol'); - symbol.textContent = symbols[Math.floor(Math.random() * symbols.length)]; - - // Randomize properties for a more natural look - symbol.style.top = `${Math.random() * 90}vh`; - symbol.style.left = `${Math.random() * 80}%`; - symbol.style.fontSize = `${Math.random() * 20 + 10}px`; - symbol.style.animationDelay = `${Math.random() * 20}s`; - symbol.style.animationDuration = `${Math.random() * 20 + 15}s`; // Duration between 15s and 35s - - container.appendChild(symbol); - } - }; - - createSymbols(leftContainer); - createSymbols(rightContainer); - }; - - getFortuneBtn.addEventListener('click', fetchFortune); - tarotCardContainer.addEventListener('click', () => { - tarotCardContainer.classList.toggle('flipped'); - }); - - // Initial actions on page load - fetchFortune(); - createSideDecorations(); -}); \ No newline at end of file diff --git a/frontend/60sapi/娱乐消遣/随机运势/接口集合.json b/frontend/60sapi/娱乐消遣/随机运势/接口集合.json deleted file mode 100755 index 547b2771..00000000 --- a/frontend/60sapi/娱乐消遣/随机运势/接口集合.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "https://60s.api.shumengya.top" -] diff --git a/frontend/60sapi/娱乐消遣/随机运势/返回接口.json b/frontend/60sapi/娱乐消遣/随机运势/返回接口.json deleted file mode 100755 index f5498794..00000000 --- a/frontend/60sapi/娱乐消遣/随机运势/返回接口.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "code": 200, - "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", - "data": { - "luck_desc": "恋愛運", - "luck_rank": 21, - "luck_tip": "闪亮的邂逅之日!顺其自然吧", - "luck_tip_index": 19 - } -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/EpicGames免费游戏/css/style.css b/frontend/60sapi/实用功能/EpicGames免费游戏/css/style.css deleted file mode 100755 index 30d4f120..00000000 --- a/frontend/60sapi/实用功能/EpicGames免费游戏/css/style.css +++ /dev/null @@ -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)); - } -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/EpicGames免费游戏/index.html b/frontend/60sapi/实用功能/EpicGames免费游戏/index.html deleted file mode 100755 index c29c106f..00000000 --- a/frontend/60sapi/实用功能/EpicGames免费游戏/index.html +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - Epic Games 免费游戏 - 60s API 集合 - - - - - -
-
-

- 🎮 Epic Games 免费游戏 -

-
- - -
-
-

正在加载游戏数据,请稍候…

-
- - - - -
- -
-
-
0
-
总游戏数
-
-
-
0
-
当前免费
-
-
-
0
-
即将免费
-
-
- - -
- -
- - -
- -
-
-
- - - - \ No newline at end of file diff --git a/frontend/60sapi/实用功能/EpicGames免费游戏/js/script.js b/frontend/60sapi/实用功能/EpicGames免费游戏/js/script.js deleted file mode 100755 index 10bd848e..00000000 --- a/frontend/60sapi/实用功能/EpicGames免费游戏/js/script.js +++ /dev/null @@ -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.shumengya.top/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 ` -
-
${statusText}
- ${safeText(game.title)} 封面 -
-

${safeText(game.title)}

-

${safeText(game.description)}

- -
-
- ${safeText(game.original_price_desc)} - 免费 -
-
${safeText(game.seller)}
-
- -
-
- 开始:${formatDate(game.free_start)} - 结束:${formatDate(game.free_end)} -
-
- - -
-
- `; - } - - 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 = '
暂无游戏数据
'; - 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(); - }); -})(); \ No newline at end of file diff --git a/frontend/60sapi/实用功能/EpicGames免费游戏/接口集合.json b/frontend/60sapi/实用功能/EpicGames免费游戏/接口集合.json deleted file mode 100755 index 547b2771..00000000 --- a/frontend/60sapi/实用功能/EpicGames免费游戏/接口集合.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "https://60s.api.shumengya.top" -] diff --git a/frontend/60sapi/实用功能/EpicGames免费游戏/返回接口.json b/frontend/60sapi/实用功能/EpicGames免费游戏/返回接口.json deleted file mode 100755 index 7804d62a..00000000 --- a/frontend/60sapi/实用功能/EpicGames免费游戏/返回接口.json +++ /dev/null @@ -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" - } - ] -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/公网IP地址/css/background.css b/frontend/60sapi/实用功能/公网IP地址/css/background.css deleted file mode 100755 index 74f65ebc..00000000 --- a/frontend/60sapi/实用功能/公网IP地址/css/background.css +++ /dev/null @@ -1,233 +0,0 @@ -/* 动态背景样式 */ -body::before { - content: ''; - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - z-index: -2; -} - -body::after { - content: ''; - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: - radial-gradient(circle at 20% 80%, rgba(120, 119, 198, 0.3) 0%, transparent 50%), - radial-gradient(circle at 80% 20%, rgba(255, 119, 198, 0.3) 0%, transparent 50%), - radial-gradient(circle at 40% 40%, rgba(120, 219, 255, 0.3) 0%, transparent 50%); - z-index: -1; - animation: backgroundMove 20s ease-in-out infinite; -} - -@keyframes backgroundMove { - 0%, 100% { - background: - radial-gradient(circle at 20% 80%, rgba(120, 119, 198, 0.3) 0%, transparent 50%), - radial-gradient(circle at 80% 20%, rgba(255, 119, 198, 0.3) 0%, transparent 50%), - radial-gradient(circle at 40% 40%, rgba(120, 219, 255, 0.3) 0%, transparent 50%); - } - 25% { - background: - radial-gradient(circle at 60% 30%, rgba(120, 119, 198, 0.3) 0%, transparent 50%), - radial-gradient(circle at 30% 70%, rgba(255, 119, 198, 0.3) 0%, transparent 50%), - radial-gradient(circle at 80% 80%, rgba(120, 219, 255, 0.3) 0%, transparent 50%); - } - 50% { - background: - radial-gradient(circle at 80% 60%, rgba(120, 119, 198, 0.3) 0%, transparent 50%), - radial-gradient(circle at 20% 30%, rgba(255, 119, 198, 0.3) 0%, transparent 50%), - radial-gradient(circle at 60% 70%, rgba(120, 219, 255, 0.3) 0%, transparent 50%); - } - 75% { - background: - radial-gradient(circle at 40% 90%, rgba(120, 119, 198, 0.3) 0%, transparent 50%), - radial-gradient(circle at 70% 10%, rgba(255, 119, 198, 0.3) 0%, transparent 50%), - radial-gradient(circle at 20% 60%, rgba(120, 219, 255, 0.3) 0%, transparent 50%); - } -} - -/* 浮动粒子效果 */ -.particles { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - pointer-events: none; - z-index: -1; -} - -.particle { - position: absolute; - width: 4px; - height: 4px; - background: rgba(255, 255, 255, 0.5); - border-radius: 50%; - animation: float 15s infinite linear; -} - -.particle:nth-child(1) { - left: 10%; - animation-delay: 0s; - animation-duration: 12s; -} - -.particle:nth-child(2) { - left: 20%; - animation-delay: 2s; - animation-duration: 18s; -} - -.particle:nth-child(3) { - left: 30%; - animation-delay: 4s; - animation-duration: 15s; -} - -.particle:nth-child(4) { - left: 40%; - animation-delay: 6s; - animation-duration: 20s; -} - -.particle:nth-child(5) { - left: 50%; - animation-delay: 8s; - animation-duration: 14s; -} - -.particle:nth-child(6) { - left: 60%; - animation-delay: 10s; - animation-duration: 16s; -} - -.particle:nth-child(7) { - left: 70%; - animation-delay: 12s; - animation-duration: 22s; -} - -.particle:nth-child(8) { - left: 80%; - animation-delay: 14s; - animation-duration: 13s; -} - -.particle:nth-child(9) { - left: 90%; - animation-delay: 16s; - animation-duration: 19s; -} - -.particle:nth-child(10) { - left: 15%; - animation-delay: 18s; - animation-duration: 17s; -} - -@keyframes float { - 0% { - transform: translateY(100vh) rotate(0deg); - opacity: 0; - } - 10% { - opacity: 1; - } - 90% { - opacity: 1; - } - 100% { - transform: translateY(-100px) rotate(360deg); - opacity: 0; - } -} - -/* 网格背景效果 */ -.grid-background { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-image: - linear-gradient(rgba(255, 255, 255, 0.1) 1px, transparent 1px), - linear-gradient(90deg, rgba(255, 255, 255, 0.1) 1px, transparent 1px); - background-size: 50px 50px; - z-index: -1; - opacity: 0.3; - animation: gridMove 30s linear infinite; -} - -@keyframes gridMove { - 0% { - transform: translate(0, 0); - } - 100% { - transform: translate(50px, 50px); - } -} - -/* 光晕效果 */ -.glow-effect { - position: fixed; - top: 50%; - left: 50%; - width: 300px; - height: 300px; - background: radial-gradient(circle, rgba(74, 144, 226, 0.2) 0%, transparent 70%); - border-radius: 50%; - transform: translate(-50%, -50%); - z-index: -1; - animation: pulse 4s ease-in-out infinite; -} - -@keyframes pulse { - 0%, 100% { - transform: translate(-50%, -50%) scale(1); - opacity: 0.5; - } - 50% { - transform: translate(-50%, -50%) scale(1.2); - opacity: 0.8; - } -} - -/* 响应式背景调整 */ -@media (max-width: 768px) { - .grid-background { - background-size: 30px 30px; - } - - .glow-effect { - width: 200px; - height: 200px; - } - - .particle { - width: 3px; - height: 3px; - } -} - -@media (max-width: 480px) { - .grid-background { - background-size: 20px 20px; - } - - .glow-effect { - width: 150px; - height: 150px; - } - - .particle { - width: 2px; - height: 2px; - } -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/公网IP地址/css/style.css b/frontend/60sapi/实用功能/公网IP地址/css/style.css deleted file mode 100755 index 30d4768f..00000000 --- a/frontend/60sapi/实用功能/公网IP地址/css/style.css +++ /dev/null @@ -1,445 +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: #333; - min-height: 100vh; - overflow-x: hidden; -} - -/* 容器样式 */ -.container { - min-height: 100vh; - display: flex; - flex-direction: column; - position: relative; - z-index: 1; -} - -/* 头部样式 */ -.header { - text-align: center; - padding: 3rem 2rem 2rem; - background: linear-gradient(135deg, rgba(74, 144, 226, 0.1), rgba(80, 200, 120, 0.1)); - backdrop-filter: blur(10px); - border-bottom: 1px solid rgba(255, 255, 255, 0.2); -} - -.header h1 { - font-size: 2.5rem; - font-weight: 700; - background: linear-gradient(135deg, #4a90e2, #50c878); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; - margin-bottom: 0.5rem; - text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); -} - -.header h1 i { - margin-right: 0.5rem; - background: linear-gradient(135deg, #4a90e2, #50c878); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; -} - -.subtitle { - font-size: 1.1rem; - color: #666; - font-weight: 300; -} - -/* 主要内容区域 */ -.main-content { - flex: 1; - padding: 2rem; - max-width: 800px; - margin: 0 auto; - width: 100%; -} - -/* 查询按钮区域 */ -.query-section { - text-align: center; - margin-bottom: 2rem; -} - -.query-btn { - background: linear-gradient(135deg, #4a90e2, #50c878); - color: white; - border: none; - padding: 1rem 2rem; - font-size: 1.1rem; - font-weight: 600; - border-radius: 50px; - cursor: pointer; - transition: all 0.3s ease; - box-shadow: 0 4px 15px rgba(74, 144, 226, 0.3); - display: inline-flex; - align-items: center; - gap: 0.5rem; - min-width: 200px; - justify-content: center; -} - -.query-btn:hover { - transform: translateY(-2px); - box-shadow: 0 6px 20px rgba(74, 144, 226, 0.4); - background: linear-gradient(135deg, #3a7bc8, #40a868); -} - -.query-btn:active { - transform: translateY(0); -} - -.query-btn:disabled { - opacity: 0.6; - cursor: not-allowed; - transform: none; -} - -/* 加载动画 */ -.loading { - text-align: center; - padding: 2rem; -} - -.spinner { - width: 50px; - height: 50px; - border: 4px solid #f3f3f3; - border-top: 4px solid #4a90e2; - border-radius: 50%; - animation: spin 1s linear infinite; - margin: 0 auto 1rem; -} - -@keyframes spin { - 0% { transform: rotate(0deg); } - 100% { transform: rotate(360deg); } -} - -.loading p { - color: #666; - font-size: 1rem; -} - -/* IP信息卡片 */ -.ip-info { - animation: fadeInUp 0.6s ease; -} - -@keyframes fadeInUp { - from { - opacity: 0; - transform: translateY(30px); - } - to { - opacity: 1; - transform: translateY(0); - } -} - -.ip-card { - background: rgba(255, 255, 255, 0.9); - backdrop-filter: blur(10px); - border-radius: 20px; - padding: 2rem; - margin-bottom: 2rem; - box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); - border: 1px solid rgba(255, 255, 255, 0.2); -} - -.ip-header { - display: flex; - align-items: center; - gap: 0.5rem; - margin-bottom: 1.5rem; - padding-bottom: 1rem; - border-bottom: 2px solid #f0f0f0; -} - -.ip-header i { - font-size: 1.5rem; - color: #4a90e2; -} - -.ip-header h2 { - font-size: 1.5rem; - font-weight: 600; - color: #333; -} - -.ip-display { - display: flex; - align-items: center; - justify-content: center; - gap: 1rem; - margin-bottom: 1.5rem; - padding: 1.5rem; - background: linear-gradient(135deg, rgba(74, 144, 226, 0.1), rgba(80, 200, 120, 0.1)); - border-radius: 15px; - border: 2px solid rgba(74, 144, 226, 0.2); -} - -.ip-address { - font-size: 2rem; - font-weight: 700; - font-family: 'Courier New', monospace; - color: #2c3e50; - background: linear-gradient(135deg, #4a90e2, #50c878); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; - text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); -} - -.copy-btn { - background: #4a90e2; - color: white; - border: none; - padding: 0.5rem; - border-radius: 8px; - cursor: pointer; - transition: all 0.3s ease; - font-size: 1rem; - width: 40px; - height: 40px; - display: flex; - align-items: center; - justify-content: center; -} - -.copy-btn:hover { - background: #3a7bc8; - transform: scale(1.1); -} - -.ip-details { - display: grid; - gap: 1rem; -} - -.detail-item { - display: flex; - align-items: center; - gap: 0.5rem; - padding: 0.75rem; - background: rgba(248, 249, 250, 0.8); - border-radius: 10px; - transition: all 0.3s ease; -} - -.detail-item:hover { - background: rgba(74, 144, 226, 0.1); - transform: translateX(5px); -} - -.detail-item i { - color: #4a90e2; - width: 20px; - text-align: center; -} - -.detail-item .label { - font-weight: 600; - color: #555; - min-width: 80px; -} - -.detail-item .value { - color: #333; - font-weight: 500; -} - -/* IP地址说明区域 */ -.ip-explanation { - background: rgba(255, 255, 255, 0.9); - backdrop-filter: blur(10px); - border-radius: 20px; - padding: 2rem; - box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); - border: 1px solid rgba(255, 255, 255, 0.2); -} - -.ip-explanation h3 { - display: flex; - align-items: center; - gap: 0.5rem; - margin-bottom: 1rem; - font-size: 1.3rem; - color: #333; -} - -.ip-explanation h3 i { - color: #4a90e2; -} - -.ip-explanation p { - color: #666; - line-height: 1.8; - margin-bottom: 1.5rem; -} - -.features { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); - gap: 1rem; -} - -.feature-item { - display: flex; - align-items: flex-start; - gap: 1rem; - padding: 1rem; - background: rgba(248, 249, 250, 0.8); - border-radius: 12px; - transition: all 0.3s ease; -} - -.feature-item:hover { - background: rgba(74, 144, 226, 0.1); - transform: translateY(-2px); -} - -.feature-item i { - color: #4a90e2; - font-size: 1.5rem; - margin-top: 0.2rem; -} - -.feature-item h4 { - font-size: 1rem; - font-weight: 600; - color: #333; - margin-bottom: 0.3rem; -} - -.feature-item p { - font-size: 0.9rem; - color: #666; - line-height: 1.5; - margin: 0; -} - -/* 错误信息 */ -.error-message { - text-align: center; - padding: 2rem; - background: rgba(255, 255, 255, 0.9); - backdrop-filter: blur(10px); - border-radius: 20px; - box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); - border: 1px solid rgba(255, 99, 99, 0.3); - animation: fadeInUp 0.6s ease; -} - -.error-message i { - font-size: 3rem; - color: #ff6b6b; - margin-bottom: 1rem; -} - -.error-message p { - color: #666; - font-size: 1.1rem; - margin-bottom: 1.5rem; -} - -.retry-btn { - background: #ff6b6b; - color: white; - border: none; - padding: 0.75rem 1.5rem; - font-size: 1rem; - font-weight: 600; - border-radius: 25px; - cursor: pointer; - transition: all 0.3s ease; -} - -.retry-btn:hover { - background: #ff5252; - transform: translateY(-2px); - box-shadow: 0 4px 15px rgba(255, 107, 107, 0.3); -} - -/* 页脚 */ -.footer { - text-align: center; - padding: 2rem; - background: rgba(248, 249, 250, 0.8); - backdrop-filter: blur(10px); - border-top: 1px solid rgba(255, 255, 255, 0.2); - color: #666; - font-size: 0.9rem; -} - -/* 响应式设计 */ -@media (max-width: 768px) { - .header { - padding: 2rem 1rem 1.5rem; - } - - .header h1 { - font-size: 2rem; - } - - .main-content { - padding: 1rem; - } - - .ip-card, .ip-explanation { - padding: 1.5rem; - } - - .ip-address { - font-size: 1.5rem; - } - - .ip-display { - flex-direction: column; - gap: 1rem; - } - - .features { - grid-template-columns: 1fr; - } - - .detail-item { - flex-direction: column; - align-items: flex-start; - gap: 0.3rem; - } - - .detail-item .label { - min-width: auto; - } -} - -@media (max-width: 480px) { - .header h1 { - font-size: 1.8rem; - } - - .query-btn { - padding: 0.875rem 1.5rem; - font-size: 1rem; - min-width: 180px; - } - - .ip-address { - font-size: 1.3rem; - } - - .ip-card, .ip-explanation { - padding: 1rem; - } -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/公网IP地址/index.html b/frontend/60sapi/实用功能/公网IP地址/index.html deleted file mode 100755 index 875fb9f0..00000000 --- a/frontend/60sapi/实用功能/公网IP地址/index.html +++ /dev/null @@ -1,139 +0,0 @@ - - - - - - 公网IP地址查询 - - - - - -
- -
-

公网IP地址查询

-

快速获取您的公网IP地址信息

-
- - -
- -
- -
- - - - - - - - - -
- - -
-

© 2024 公网IP地址查询工具 | 数据来源: 60s.viki.moe

-
-
- - - - \ No newline at end of file diff --git a/frontend/60sapi/实用功能/公网IP地址/js/script.js b/frontend/60sapi/实用功能/公网IP地址/js/script.js deleted file mode 100755 index c982e386..00000000 --- a/frontend/60sapi/实用功能/公网IP地址/js/script.js +++ /dev/null @@ -1,343 +0,0 @@ -// 公网IP地址查询应用 -class IPQueryApp { - constructor() { - this.apiEndpoint = 'https://60s.api.shumengya.top/v2/ip'; - this.init(); - } - - // 初始化应用 - init() { - this.bindEvents(); - this.createParticles(); - this.createBackgroundElements(); - console.log('IP查询应用初始化完成'); - } - - // 绑定事件 - bindEvents() { - const queryBtn = document.getElementById('queryBtn'); - const retryBtn = document.getElementById('retryBtn'); - const copyBtn = document.getElementById('copyBtn'); - - if (queryBtn) { - queryBtn.addEventListener('click', () => this.queryIP()); - } - - if (retryBtn) { - retryBtn.addEventListener('click', () => this.queryIP()); - } - - if (copyBtn) { - copyBtn.addEventListener('click', () => this.copyIP()); - } - - // 页面加载完成后自动查询一次 - document.addEventListener('DOMContentLoaded', () => { - setTimeout(() => this.queryIP(), 500); - }); - } - - // 创建浮动粒子 - createParticles() { - const particlesContainer = document.createElement('div'); - particlesContainer.className = 'particles'; - document.body.appendChild(particlesContainer); - - for (let i = 0; i < 10; i++) { - const particle = document.createElement('div'); - particle.className = 'particle'; - particlesContainer.appendChild(particle); - } - } - - // 创建背景元素 - createBackgroundElements() { - // 创建网格背景 - const gridBackground = document.createElement('div'); - gridBackground.className = 'grid-background'; - document.body.appendChild(gridBackground); - - // 创建光晕效果 - const glowEffect = document.createElement('div'); - glowEffect.className = 'glow-effect'; - document.body.appendChild(glowEffect); - } - - // 显示加载状态 - showLoading() { - const loading = document.getElementById('loading'); - const ipInfo = document.getElementById('ipInfo'); - const errorMessage = document.getElementById('errorMessage'); - const queryBtn = document.getElementById('queryBtn'); - - if (loading) loading.style.display = 'block'; - if (ipInfo) ipInfo.style.display = 'none'; - if (errorMessage) errorMessage.style.display = 'none'; - if (queryBtn) { - queryBtn.disabled = true; - queryBtn.innerHTML = ' 查询中...'; - } - } - - // 隐藏加载状态 - hideLoading() { - const loading = document.getElementById('loading'); - const queryBtn = document.getElementById('queryBtn'); - - if (loading) loading.style.display = 'none'; - if (queryBtn) { - queryBtn.disabled = false; - queryBtn.innerHTML = ' 查询我的IP'; - } - } - - // 显示错误信息 - showError(message) { - const errorMessage = document.getElementById('error-message'); - const ipInfo = document.getElementById('ip-info'); - - if (errorMessage) { - errorMessage.style.display = 'block'; - const errorText = errorMessage.querySelector('p'); - if (errorText) errorText.textContent = message || '获取IP信息失败,请稍后重试'; - } - if (ipInfo) ipInfo.style.display = 'none'; - - this.hideLoading(); - } - - // 查询IP地址 - async queryIP() { - try { - this.showLoading(); - console.log('开始查询IP地址...'); - - const response = await fetch(this.apiEndpoint, { - method: 'GET', - headers: { - 'Accept': 'application/json', - 'Content-Type': 'application/json' - } - }); - - console.log('API响应状态:', response.status); - - if (!response.ok) { - throw new Error(`HTTP错误: ${response.status}`); - } - - const data = await response.json(); - console.log('API返回数据:', data); - - if (data.code === 200 && data.data) { - this.displayIPInfo(data.data); - } else { - throw new Error(data.message || '获取IP信息失败'); - } - - } catch (error) { - console.error('查询IP失败:', error); - this.showError(error.message); - } - } - - // 显示IP信息 - displayIPInfo(data) { - const ipInfo = document.getElementById('ip-info'); - const errorMessage = document.getElementById('error-message'); - - // 更新IP地址显示 - const ipAddressElement = document.getElementById('ip-address'); - if (ipAddressElement && data.ip) { - ipAddressElement.textContent = data.ip; - } - - // 更新查询时间 - const queryTimeElement = document.getElementById('query-time'); - if (queryTimeElement) { - const now = new Date(); - queryTimeElement.textContent = now.toLocaleString('zh-CN'); - } - - // 更新详细信息 - 只显示API提供的数据 - if (data.location) this.updateDetailItem('location', data.location); - else this.hideDetailItem('location'); - - if (data.isp) this.updateDetailItem('isp', data.isp); - else this.hideDetailItem('isp'); - - if (data.country) this.updateDetailItem('country', data.country); - else this.hideDetailItem('country'); - - if (data.region) this.updateDetailItem('region', data.region); - else this.hideDetailItem('region'); - - if (data.city) this.updateDetailItem('city', data.city); - else this.hideDetailItem('city'); - - if (data.timezone) this.updateDetailItem('timezone', data.timezone); - else this.hideDetailItem('timezone'); - - // 显示IP信息,隐藏错误信息 - if (ipInfo) ipInfo.style.display = 'block'; - if (errorMessage) errorMessage.style.display = 'none'; - - this.hideLoading(); - console.log('IP信息显示完成'); - } - - // 更新详细信息项 - updateDetailItem(id, value) { - const element = document.getElementById(id); - if (element) { - element.textContent = value; - // 显示对应的详细信息行 - const detailRow = element.closest('.detail-item'); - if (detailRow) { - detailRow.style.display = 'flex'; - } - } - } - - // 隐藏详细信息项 - hideDetailItem(id) { - const element = document.getElementById(id); - if (element) { - // 隐藏整个详细信息行 - const detailRow = element.closest('.detail-item'); - if (detailRow) { - detailRow.style.display = 'none'; - } - } - } - - // 复制IP地址 - async copyIP() { - const ipAddressElement = document.getElementById('ip-address'); - const copyBtn = document.getElementById('copyBtn'); - - if (!ipAddressElement || !ipAddressElement.textContent) { - this.showToast('没有可复制的IP地址', 'error'); - return; - } - - try { - await navigator.clipboard.writeText(ipAddressElement.textContent); - - // 更新按钮状态 - if (copyBtn) { - const originalHTML = copyBtn.innerHTML; - copyBtn.innerHTML = ''; - copyBtn.style.background = '#50c878'; - - setTimeout(() => { - copyBtn.innerHTML = originalHTML; - copyBtn.style.background = '#4a90e2'; - }, 1500); - } - - this.showToast('IP地址已复制到剪贴板', 'success'); - console.log('IP地址已复制:', ipAddressElement.textContent); - - } catch (error) { - console.error('复制失败:', error); - this.showToast('复制失败,请手动选择复制', 'error'); - } - } - - // 显示提示消息 - showToast(message, type = 'info') { - // 移除已存在的toast - const existingToast = document.querySelector('.toast'); - if (existingToast) { - existingToast.remove(); - } - - // 创建新的toast - const toast = document.createElement('div'); - toast.className = `toast toast-${type}`; - toast.innerHTML = ` - - ${message} - `; - - // 添加toast样式 - toast.style.cssText = ` - position: fixed; - top: 20px; - right: 20px; - background: ${type === 'success' ? '#50c878' : type === 'error' ? '#ff6b6b' : '#4a90e2'}; - color: white; - padding: 1rem 1.5rem; - border-radius: 10px; - box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); - z-index: 1000; - display: flex; - align-items: center; - gap: 0.5rem; - font-weight: 500; - animation: slideInRight 0.3s ease; - max-width: 300px; - `; - - // 添加动画样式 - 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'; - setTimeout(() => { - if (toast.parentNode) { - toast.remove(); - } - if (style.parentNode) { - style.remove(); - } - }, 300); - }, 3000); - } - - // 格式化时间 - formatTime(timestamp) { - const date = new Date(timestamp); - return date.toLocaleString('zh-CN', { - year: 'numeric', - month: '2-digit', - day: '2-digit', - hour: '2-digit', - minute: '2-digit', - second: '2-digit' - }); - } -} - -// 初始化应用 -const app = new IPQueryApp(); - -// 导出到全局作用域(用于调试) -window.IPQueryApp = app; \ No newline at end of file diff --git a/frontend/60sapi/实用功能/公网IP地址/接口集合.json b/frontend/60sapi/实用功能/公网IP地址/接口集合.json deleted file mode 100755 index 36e557bf..00000000 --- a/frontend/60sapi/实用功能/公网IP地址/接口集合.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "https://60s.api.shumengya.top/v2/ip" -] \ No newline at end of file diff --git a/frontend/60sapi/实用功能/公网IP地址/返回接口.json b/frontend/60sapi/实用功能/公网IP地址/返回接口.json deleted file mode 100755 index d10b040f..00000000 --- a/frontend/60sapi/实用功能/公网IP地址/返回接口.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "code": 200, - "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", - "data": { - "ip": "2401:b60:16:83::" - } -} - -// 注意:此API只返回IP地址,不包含以下信息: -// - location (位置信息) -// - isp (网络服务商) -// - country (国家) -// - region (地区) -// - city (城市) -// - timezone (时区) -// -// 如需这些信息,需要使用其他API服务 \ No newline at end of file diff --git a/frontend/60sapi/实用功能/农历信息/css/background.css b/frontend/60sapi/实用功能/农历信息/css/background.css deleted file mode 100755 index 245ce898..00000000 --- a/frontend/60sapi/实用功能/农历信息/css/background.css +++ /dev/null @@ -1,575 +0,0 @@ -/* 农历主题背景样式 - 动态调节版本 */ -body { - background: linear-gradient(135deg, - #fff8dc 0%, /* 玉米丝色 */ - #ffd700 20%, /* 金黄色 */ - #ffcc00 40%, /* 亮金色 */ - #daa520 60%, /* 深金色 */ - #b8860b 80%, /* 暗金色 */ - #fff8dc 100% /* 玉米丝色 */ - ); - background-size: 400% 400%; - animation: goldenShift 25s ease infinite; - background-attachment: fixed; - min-height: 100vh; - position: relative; -} - -@keyframes goldenShift { - 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%; } -} - -/* 动态颜色调节系统 */ -.adaptive-overlay { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: - radial-gradient(circle at 20% 30%, rgba(255, 255, 255, 0.1) 0%, transparent 50%), - radial-gradient(circle at 80% 70%, rgba(255, 255, 255, 0.15) 0%, transparent 50%), - linear-gradient(45deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.2) 100%); - pointer-events: none; - z-index: 1; - animation: adaptiveShift 60s ease infinite; -} - -@keyframes adaptiveShift { - 0% { - background: - radial-gradient(circle at 20% 30%, rgba(255, 255, 255, 0.1) 0%, transparent 50%), - radial-gradient(circle at 80% 70%, rgba(255, 255, 255, 0.15) 0%, transparent 50%), - linear-gradient(45deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.2) 100%); - } - 25% { - background: - radial-gradient(circle at 70% 20%, rgba(255, 255, 255, 0.2) 0%, transparent 50%), - radial-gradient(circle at 30% 80%, rgba(255, 255, 255, 0.1) 0%, transparent 50%), - linear-gradient(135deg, rgba(255, 255, 255, 0.15) 0%, rgba(255, 255, 255, 0.25) 100%); - } - 50% { - background: - radial-gradient(circle at 50% 50%, rgba(255, 255, 255, 0.15) 0%, transparent 50%), - radial-gradient(circle at 10% 90%, rgba(255, 255, 255, 0.12) 0%, transparent 50%), - linear-gradient(225deg, rgba(255, 255, 255, 0.12) 0%, rgba(255, 255, 255, 0.22) 100%); - } - 75% { - background: - radial-gradient(circle at 90% 60%, rgba(255, 255, 255, 0.18) 0%, transparent 50%), - radial-gradient(circle at 40% 10%, rgba(255, 255, 255, 0.08) 0%, transparent 50%), - linear-gradient(315deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.2) 100%); - } - 100% { - background: - radial-gradient(circle at 20% 30%, rgba(255, 255, 255, 0.1) 0%, transparent 50%), - radial-gradient(circle at 80% 70%, rgba(255, 255, 255, 0.15) 0%, transparent 50%), - linear-gradient(45deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.2) 100%); - } -} - -/* 高清稻穗贴图层 */ -body::before { - content: ''; - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-image: - /* 主稻穗束 - 高清细节 */ - radial-gradient(ellipse 1.5px 12px at 50% 45%, #DAA520 0%, #B8860B 30%, transparent 80%), - radial-gradient(ellipse 1px 10px at 48% 50%, #FFD700 0%, #DAA520 40%, transparent 75%), - radial-gradient(ellipse 1.2px 11px at 52% 48%, #FFCC00 0%, #B8860B 35%, transparent 78%), - radial-gradient(ellipse 0.8px 9px at 49% 52%, #F4A460 0%, #DAA520 45%, transparent 70%), - radial-gradient(ellipse 1.3px 13px at 51% 46%, #DEB887 0%, #B8860B 38%, transparent 82%), - - /* 次级稻穗 */ - radial-gradient(ellipse 1px 8px at 30% 35%, #FFD700 0%, #DAA520 50%, transparent 75%), - radial-gradient(ellipse 0.9px 7px at 32% 38%, #FFCC00 0%, #B8860B 45%, transparent 70%), - radial-gradient(ellipse 1.1px 9px at 28% 36%, #DEB887 0%, #DAA520 40%, transparent 78%), - - radial-gradient(ellipse 1px 8px at 70% 65%, #FFD700 0%, #DAA520 50%, transparent 75%), - radial-gradient(ellipse 0.8px 7px at 72% 68%, #F4A460 0%, #B8860B 45%, transparent 70%), - radial-gradient(ellipse 1.2px 9px at 68% 66%, #FFCC00 0%, #DAA520 40%, transparent 78%), - - /* 散落稻粒 */ - radial-gradient(ellipse 0.5px 4px at 20% 80%, #FFD700 0%, transparent 60%), - radial-gradient(ellipse 0.6px 5px at 80% 20%, #FFCC00 0%, transparent 65%), - radial-gradient(ellipse 0.4px 3px at 15% 25%, #DEB887 0%, transparent 55%), - radial-gradient(ellipse 0.7px 6px at 85% 75%, #DAA520 0%, transparent 70%), - - /* 稻穗茎秆 - 更细致 */ - linear-gradient(88deg, transparent 49%, #9ACD32 49.5%, #8FBC8F 50%, #9ACD32 50.5%, transparent 51%), - linear-gradient(92deg, transparent 49%, #8FBC8F 49.5%, #228B22 50%, #8FBC8F 50.5%, transparent 51%), - linear-gradient(85deg, transparent 49%, #32CD32 49.5%, #9ACD32 50%, #32CD32 50.5%, transparent 51%); - - background-size: - 25px 25px, 24px 24px, 26px 26px, 23px 23px, 27px 27px, - 20px 20px, 19px 19px, 21px 21px, - 22px 22px, 18px 18px, 23px 23px, - 15px 15px, 16px 16px, 14px 14px, 17px 17px, - 80px 80px, 85px 85px, 75px 75px; - - background-position: - 0 0, 12px 12px, 6px 18px, 18px 6px, 3px 21px, - 40px 40px, 52px 48px, 35px 55px, - 120px 120px, 135px 115px, 110px 130px, - 200px 200px, 220px 180px, 180px 220px, 240px 160px, - 0 0, 40px 40px, 20px 60px; - - opacity: 0.25; - pointer-events: none; - z-index: -2; - animation: wheatSway 20s ease-in-out infinite; -} - -@keyframes wheatSway { - 0%, 100% { - transform: translateX(0) rotate(0deg); - } - 25% { - transform: translateX(5px) rotate(0.5deg); - } - 50% { - transform: translateX(-3px) rotate(-0.3deg); - } - 75% { - transform: translateX(2px) rotate(0.2deg); - } -} - -/* 大型稻穗背景层 */ -body::after { - content: ''; - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-image: - /* 主稻穗茎秆 - 右侧大型 */ - linear-gradient(85deg, transparent 45%, #9ACD32 47%, #8FBC8F 48%, #228B22 49%, #8FBC8F 50%, #9ACD32 51%, transparent 53%), - linear-gradient(87deg, transparent 46%, #32CD32 47.5%, #9ACD32 48.5%, #8FBC8F 49.5%, #9ACD32 50.5%, #32CD32 51.5%, transparent 54%), - - /* 主稻穗穗头 - 大型椭圆稻粒群 */ - radial-gradient(ellipse 8px 25px at 75% 15%, #FFD700 0%, #DAA520 30%, #B8860B 60%, transparent 85%), - radial-gradient(ellipse 7px 23px at 77% 18%, #FFCC00 0%, #DAA520 35%, transparent 80%), - radial-gradient(ellipse 9px 27px at 73% 12%, #F4A460 0%, #B8860B 40%, transparent 88%), - radial-gradient(ellipse 6px 22px at 79% 20%, #DEB887 0%, #DAA520 45%, transparent 75%), - radial-gradient(ellipse 8px 24px at 75% 16%, #FFD700 0%, #B8860B 38%, transparent 82%), - - /* 稻穗分支 */ - radial-gradient(ellipse 5px 18px at 72% 25%, #FFCC00 0%, #DAA520 50%, transparent 75%), - radial-gradient(ellipse 4px 16px at 78% 28%, #F4A460 0%, #B8860B 45%, transparent 70%), - radial-gradient(ellipse 6px 20px at 70% 22%, #DEB887 0%, #DAA520 40%, transparent 78%), - radial-gradient(ellipse 5px 17px at 80% 30%, #FFD700 0%, #B8860B 42%, transparent 76%), - - /* 左侧稻穗茎秆 */ - linear-gradient(95deg, transparent 15%, #9ACD32 17%, #8FBC8F 18%, #228B22 19%, #8FBC8F 20%, #9ACD32 21%, transparent 23%), - - /* 左侧稻穗穗头 */ - radial-gradient(ellipse 6px 20px at 25% 25%, #FFD700 0%, #DAA520 30%, transparent 80%), - radial-gradient(ellipse 5px 18px at 27% 28%, #FFCC00 0%, #B8860B 35%, transparent 75%), - radial-gradient(ellipse 7px 22px at 23% 22%, #F4A460 0%, #DAA520 40%, transparent 85%), - - /* 麦田远景效果 */ - linear-gradient(180deg, transparent 70%, rgba(255, 215, 0, 0.1) 75%, rgba(218, 165, 32, 0.15) 85%, rgba(255, 215, 0, 0.2) 95%, rgba(255, 215, 0, 0.25) 100%), - - /* 散落稻粒 */ - radial-gradient(ellipse 2px 8px at 60% 40%, #FFD700 0%, transparent 60%), - radial-gradient(ellipse 1.5px 6px at 40% 60%, #FFCC00 0%, transparent 65%), - radial-gradient(ellipse 2.5px 10px at 85% 50%, #DEB887 0%, transparent 70%), - radial-gradient(ellipse 1.8px 7px at 15% 80%, #DAA520 0%, transparent 68%); - - background-size: - /* 主茎秆 */ - 100vw 80vh, 100vw 82vh, - /* 主穗头 */ - 50vw 60vh, 48vw 58vh, 52vw 62vh, 46vw 56vh, 50vw 60vh, - /* 分支 */ - 40vw 50vh, 38vw 48vh, 42vw 52vh, 36vw 46vh, - /* 左侧茎秆 */ - 100vw 70vh, - /* 左侧穗头 */ - 35vw 45vh, 33vw 43vh, 37vw 47vh, - /* 麦田远景 */ - 100vw 100vh, - /* 散落稻粒 */ - 20vw 20vh, 25vw 25vh, 30vw 30vh, 22vw 22vh; - - background-position: - /* 主茎秆 */ - 70% 20%, 72% 18%, - /* 主穗头 */ - 60% 0%, 62% 2%, 58% -2%, 64% 4%, 60% 1%, - /* 分支 */ - 65% 15%, 67% 17%, 63% 13%, 69% 19%, - /* 左侧茎秆 */ - 20% 30%, - /* 左侧穗头 */ - 15% 20%, 17% 22%, 13% 18%, - /* 麦田远景 */ - 0% 0%, - /* 散落稻粒 */ - 30% 50%, 50% 70%, 80% 40%, 10% 80%; - - background-repeat: no-repeat; - opacity: 0.4; - pointer-events: none; - z-index: -1; - animation: wheatSway 25s ease-in-out infinite; -} - -@keyframes spiralRotate { - 0% { - transform: rotate(0deg); - } - 100% { - transform: rotate(360deg); - } -} - -/* 流星效果容器 */ -.meteor-container { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - pointer-events: none; - z-index: -1; - overflow: hidden; -} - -/* 流星轨迹 */ -.meteor { - position: absolute; - width: 2px; - height: 2px; - background: radial-gradient(circle, #FFD700 0%, #FFA500 50%, transparent 100%); - border-radius: 50%; - box-shadow: - 0 0 10px #FFD700, - 0 0 20px #FFA500, - 0 0 30px #FF8C00; - animation: meteorFall linear infinite; -} - -/* 流星尾迹 */ -.meteor::before { - content: ''; - position: absolute; - top: 0; - left: 0; - width: 100px; - height: 1px; - background: linear-gradient(90deg, - #FFD700 0%, - #FFA500 30%, - #FF8C00 60%, - transparent 100%); - transform-origin: 0 50%; - transform: rotate(-45deg); - opacity: 0.8; -} - -@keyframes meteorFall { - 0% { - transform: translateX(-100px) translateY(-100px); - opacity: 0; - } - 10% { - opacity: 1; - } - 90% { - opacity: 1; - } - 100% { - transform: translateX(calc(100vw + 100px)) translateY(calc(100vh + 100px)); - opacity: 0; - } -} - -/* 多个流星的不同轨迹 */ -.meteor:nth-child(1) { - top: 10%; - left: -100px; - animation-duration: 8s; - animation-delay: 0s; -} - -.meteor:nth-child(2) { - top: 20%; - left: -100px; - animation-duration: 12s; - animation-delay: 2s; -} - -.meteor:nth-child(3) { - top: 30%; - left: -100px; - animation-duration: 10s; - animation-delay: 4s; -} - -.meteor:nth-child(4) { - top: 50%; - left: -100px; - animation-duration: 15s; - animation-delay: 6s; -} - -.meteor:nth-child(5) { - top: 70%; - left: -100px; - animation-duration: 9s; - animation-delay: 8s; -} - -.meteor:nth-child(6) { - top: 80%; - left: -100px; - animation-duration: 11s; - animation-delay: 10s; -} - -/* 金色粒子效果 */ -.golden-particles { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - pointer-events: none; - z-index: -1; -} - -.particle { - position: absolute; - width: 3px; - height: 3px; - background: radial-gradient(circle, #FFD700 0%, #FFA500 70%, transparent 100%); - border-radius: 50%; - animation: particleFloat linear infinite; -} - -@keyframes particleFloat { - 0% { - transform: translateY(100vh) rotate(0deg); - opacity: 0; - } - 10% { - opacity: 1; - } - 90% { - opacity: 1; - } - 100% { - transform: translateY(-100px) rotate(360deg); - opacity: 0; - } -} - -/* 粒子的不同位置和动画时长 */ -.particle:nth-child(1) { left: 10%; animation-duration: 20s; animation-delay: 0s; } -.particle:nth-child(2) { left: 20%; animation-duration: 25s; animation-delay: 2s; } -.particle:nth-child(3) { left: 30%; animation-duration: 18s; animation-delay: 4s; } -.particle:nth-child(4) { left: 40%; animation-duration: 22s; animation-delay: 6s; } -.particle:nth-child(5) { left: 50%; animation-duration: 24s; animation-delay: 8s; } -.particle:nth-child(6) { left: 60%; animation-duration: 19s; animation-delay: 10s; } -.particle:nth-child(7) { left: 70%; animation-duration: 21s; animation-delay: 12s; } -.particle:nth-child(8) { left: 80%; animation-duration: 23s; animation-delay: 14s; } -.particle:nth-child(9) { left: 90%; animation-duration: 26s; animation-delay: 16s; } - -/* 响应式设计 */ -@media (max-width: 768px) { - .meteor { - width: 1px; - height: 1px; - } - - .meteor::before { - width: 50px; - } - - .particle { - width: 2px; - height: 2px; - } - - body::before { - background-size: - 30px 30px, 25px 25px, 35px 35px, 28px 28px, 32px 32px, - 40px 40px, 45px 45px; - } - - body::after { - background-size: 200px 200px, 150px 150px, 100px 100px; - } -} - -/* 麦穗飘舞特效 */ -.wheat-floating { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - pointer-events: none; - z-index: 2; - overflow: hidden; -} - -/* 移动设备性能优化 */ -@media (max-width: 768px) { - .wheat-floating { - display: none; - } - - .golden-particles { - display: none; - } - - .meteor-container { - display: none; - } - - .adaptive-overlay { - animation: none; - background: rgba(255, 255, 255, 0.1); - } -} - -.wheat-particle { - position: absolute; - width: 8px; - height: 20px; - background: linear-gradient(180deg, - #FFD700 0%, - #DAA520 50%, - #B8860B 100% - ); - border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%; - opacity: 0.7; - animation: wheatFloat 15s linear infinite; -} - -.wheat-particle::before { - content: ''; - position: absolute; - top: -3px; - left: 50%; - transform: translateX(-50%); - width: 2px; - height: 8px; - background: #8B7355; - border-radius: 1px; -} - -.wheat-particle::after { - content: ''; - position: absolute; - top: 2px; - left: 1px; - width: 2px; - height: 4px; - background: #FFEC8C; - border-radius: 50%; - box-shadow: - 3px 2px 0 #FFEC8C, - 1px 6px 0 #FFEC8C, - 4px 8px 0 #FFEC8C; -} - -@keyframes wheatFloat { - 0% { - transform: translateY(-100vh) translateX(0) rotate(0deg); - opacity: 0; - } - 10% { - opacity: 0.7; - } - 90% { - opacity: 0.7; - } - 100% { - transform: translateY(100vh) translateX(50px) rotate(360deg); - opacity: 0; - } -} - -/* 不同大小和速度的麦穗 */ -.wheat-particle:nth-child(1) { - left: 10%; - animation-duration: 12s; - animation-delay: 0s; - transform: scale(0.8); -} - -.wheat-particle:nth-child(2) { - left: 25%; - animation-duration: 18s; - animation-delay: 2s; - transform: scale(1.2); -} - -.wheat-particle:nth-child(3) { - left: 40%; - animation-duration: 15s; - animation-delay: 4s; - transform: scale(0.9); -} - -.wheat-particle:nth-child(4) { - left: 60%; - animation-duration: 20s; - animation-delay: 1s; - transform: scale(1.1); -} - -.wheat-particle:nth-child(5) { - left: 75%; - animation-duration: 14s; - animation-delay: 3s; - transform: scale(0.7); -} - -.wheat-particle:nth-child(6) { - left: 90%; - animation-duration: 16s; - animation-delay: 5s; - transform: scale(1.0); -} - -.wheat-particle:nth-child(7) { - left: 5%; - animation-duration: 22s; - animation-delay: 6s; - transform: scale(0.6); -} - -.wheat-particle:nth-child(8) { - left: 35%; - animation-duration: 13s; - animation-delay: 2.5s; - transform: scale(1.3); -} - -/* 减少动画偏好设置 */ -@media (prefers-reduced-motion: reduce) { - * { - animation-duration: 0.01ms !important; - animation-iteration-count: 1 !important; - transition-duration: 0.01ms !important; - } - - .meteor, - .particle { - display: none; - } -} diff --git a/frontend/60sapi/实用功能/农历信息/css/style.css b/frontend/60sapi/实用功能/农历信息/css/style.css deleted file mode 100755 index d587d194..00000000 --- a/frontend/60sapi/实用功能/农历信息/css/style.css +++ /dev/null @@ -1,1398 +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: #2c3e50; - overflow-x: hidden; - animation: textColorShift 25s ease infinite; -} - -@keyframes textColorShift { - 0% { - color: #2c3e50; - text-shadow: 1px 1px 2px rgba(255, 255, 255, 0.8); - } - 25% { - color: #1a252f; - text-shadow: 2px 2px 4px rgba(255, 255, 255, 0.9); - } - 50% { - color: #34495e; - text-shadow: 1px 1px 3px rgba(255, 255, 255, 0.7); - } - 75% { - color: #2c3e50; - text-shadow: 2px 2px 4px rgba(255, 255, 255, 0.8); - } - 100% { - color: #2c3e50; - text-shadow: 1px 1px 2px rgba(255, 255, 255, 0.8); - } -} - -/* 容器 */ -.container { - max-width: 1200px; - margin: 0 auto; - padding: 20px; - animation: containerFadeIn 1s ease-out; -} - -@keyframes containerFadeIn { - from { - opacity: 0; - transform: translateY(30px); - } - to { - opacity: 1; - transform: translateY(0); - } -} - -/* 玻璃拟态基础样式 - 动态调节版本 */ -.glass-morphism { - background: rgba(255, 255, 255, 0.15); - backdrop-filter: blur(20px); - -webkit-backdrop-filter: blur(20px); - border: 1px solid rgba(255, 255, 255, 0.2); - box-shadow: - 0 8px 32px 0 rgba(31, 38, 135, 0.15), - inset 0 1px 0 rgba(255, 255, 255, 0.3); - border-radius: 20px; - animation: glassColorShift 25s ease infinite; -} - -@keyframes glassColorShift { - 0% { - background: rgba(255, 255, 255, 0.15); - border-color: rgba(255, 255, 255, 0.2); - box-shadow: - 0 8px 32px 0 rgba(31, 38, 135, 0.15), - inset 0 1px 0 rgba(255, 255, 255, 0.3); - } - 25% { - background: rgba(255, 255, 255, 0.25); - border-color: rgba(255, 255, 255, 0.35); - box-shadow: - 0 8px 32px 0 rgba(31, 38, 135, 0.25), - inset 0 1px 0 rgba(255, 255, 255, 0.5); - } - 50% { - background: rgba(255, 255, 255, 0.18); - border-color: rgba(255, 255, 255, 0.25); - box-shadow: - 0 8px 32px 0 rgba(31, 38, 135, 0.18), - inset 0 1px 0 rgba(255, 255, 255, 0.35); - } - 75% { - background: rgba(255, 255, 255, 0.22); - border-color: rgba(255, 255, 255, 0.3); - box-shadow: - 0 8px 32px 0 rgba(31, 38, 135, 0.2), - inset 0 1px 0 rgba(255, 255, 255, 0.4); - } - 100% { - background: rgba(255, 255, 255, 0.15); - border-color: rgba(255, 255, 255, 0.2); - box-shadow: - 0 8px 32px 0 rgba(31, 38, 135, 0.15), - inset 0 1px 0 rgba(255, 255, 255, 0.3); - } -} - -/* 头部 - 动态调节版本 */ -.header { - text-align: center; - margin-bottom: 40px; - background: rgba(255, 255, 255, 0.1); - backdrop-filter: blur(25px); - -webkit-backdrop-filter: blur(25px); - padding: 40px 30px; - border-radius: 25px; - border: 1px solid rgba(255, 255, 255, 0.2); - box-shadow: - 0 8px 32px 0 rgba(31, 38, 135, 0.2), - inset 0 1px 0 rgba(255, 255, 255, 0.4); - position: relative; - overflow: hidden; - animation: headerColorShift 25s ease infinite; -} - -@keyframes headerColorShift { - 0% { - background: rgba(255, 255, 255, 0.1); - border-color: rgba(255, 255, 255, 0.2); - box-shadow: - 0 8px 32px 0 rgba(31, 38, 135, 0.2), - inset 0 1px 0 rgba(255, 255, 255, 0.4); - } - 25% { - background: rgba(255, 255, 255, 0.2); - border-color: rgba(255, 255, 255, 0.35); - box-shadow: - 0 8px 32px 0 rgba(31, 38, 135, 0.3), - inset 0 1px 0 rgba(255, 255, 255, 0.6); - } - 50% { - background: rgba(255, 255, 255, 0.15); - border-color: rgba(255, 255, 255, 0.25); - box-shadow: - 0 8px 32px 0 rgba(31, 38, 135, 0.22), - inset 0 1px 0 rgba(255, 255, 255, 0.45); - } - 75% { - background: rgba(255, 255, 255, 0.18); - border-color: rgba(255, 255, 255, 0.3); - box-shadow: - 0 8px 32px 0 rgba(31, 38, 135, 0.25), - inset 0 1px 0 rgba(255, 255, 255, 0.5); - } - 100% { - background: rgba(255, 255, 255, 0.1); - border-color: rgba(255, 255, 255, 0.2); - box-shadow: - 0 8px 32px 0 rgba(31, 38, 135, 0.2), - inset 0 1px 0 rgba(255, 255, 255, 0.4); - } -} - -.header::before { - content: ''; - position: absolute; - top: 0; - left: -100%; - width: 100%; - height: 100%; - background: linear-gradient(90deg, - transparent, - rgba(255, 255, 255, 0.1), - transparent - ); - animation: headerShimmer 6s ease-in-out infinite; -} - -@keyframes headerShimmer { - 0% { left: -100%; } - 50% { left: 100%; } - 100% { left: 100%; } -} - -.header-icon { - font-size: 4em; - margin-bottom: 15px; - animation: iconFloat 3s ease-in-out infinite; - text-shadow: 0 0 20px rgba(255, 255, 255, 0.5); -} - -@keyframes iconFloat { - 0%, 100% { - transform: translateY(0) scale(1); - filter: drop-shadow(0 0 10px rgba(255, 255, 255, 0.3)); - } - 50% { - transform: translateY(-10px) scale(1.05); - filter: drop-shadow(0 5px 15px rgba(255, 255, 255, 0.5)); - } -} - -.title { - font-size: 3.2em; - font-weight: 800; - color: #2c3e50; - margin-bottom: 10px; - text-shadow: 1px 1px 2px rgba(255, 255, 255, 0.8), 0 0 4px rgba(255, 255, 255, 0.6); - letter-spacing: 2px; - animation: titleGlow 4s ease-in-out infinite alternate, titleColorShift 25s ease infinite; -} - -@keyframes titleColorShift { - 0% { - color: #2c3e50; - text-shadow: 1px 1px 2px rgba(255, 255, 255, 0.8), 0 0 4px rgba(255, 255, 255, 0.6); - } - 25% { - color: #3498db; - text-shadow: 1px 1px 3px rgba(255, 255, 255, 0.9), 0 0 6px rgba(52, 152, 219, 0.4); - } - 50% { - color: #e74c3c; - text-shadow: 1px 1px 2px rgba(255, 255, 255, 0.7), 0 0 5px rgba(231, 76, 60, 0.3); - } - 75% { - color: #f39c12; - text-shadow: 1px 1px 3px rgba(255, 255, 255, 0.8), 0 0 6px rgba(243, 156, 18, 0.4); - } - 100% { - color: #2c3e50; - text-shadow: 1px 1px 2px rgba(255, 255, 255, 0.8), 0 0 4px rgba(255, 255, 255, 0.6); - } -} - -@keyframes titleGlow { - 0% { - text-shadow: 1px 1px 2px rgba(255, 255, 255, 0.8), 0 0 4px rgba(255, 255, 255, 0.6); - color: #2c3e50; - } - 100% { - text-shadow: 2px 2px 4px rgba(255, 255, 255, 0.9), 0 0 8px rgba(255, 255, 255, 0.7); - color: #3498db; - } -} - -.subtitle { - font-size: 1.3em; - color: #7f8c8d; - margin-bottom: 30px; - font-weight: 600; - text-shadow: 0 1px 2px rgba(255, 255, 255, 0.8); - animation: subtitleColorShift 25s ease infinite; -} - -@keyframes subtitleColorShift { - 0% { - color: #7f8c8d; - text-shadow: 0 1px 2px rgba(255, 255, 255, 0.8); - } - 25% { - color: #9b59b6; - text-shadow: 0 1px 3px rgba(255, 255, 255, 0.9); - } - 50% { - color: #e67e22; - text-shadow: 0 1px 2px rgba(255, 255, 255, 0.7); - } - 75% { - color: #27ae60; - text-shadow: 0 1px 3px rgba(255, 255, 255, 0.8); - } - 100% { - color: #7f8c8d; - text-shadow: 0 1px 2px rgba(255, 255, 255, 0.8); - } -} - -/* 日期选择器 */ -.date-selector { - display: flex; - align-items: flex-end; - justify-content: center; - gap: 20px; - margin-bottom: 25px; - flex-wrap: wrap; -} - -.input-group { - display: flex; - flex-direction: column; - gap: 8px; - min-width: 200px; -} - -.input-label { - display: flex; - align-items: center; - gap: 8px; - color: #0f1419; - font-weight: 600; - font-size: 1em; - text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.6); - animation: labelColorShift 25s ease infinite; -} - -@keyframes labelColorShift { - 0% { - color: #0f1419; - text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.6); - } - 25% { - color: #1a252f; - text-shadow: 2px 2px 3px rgba(0, 0, 0, 0.7); - } - 50% { - color: #2c3e50; - text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.5); - } - 75% { - color: #0f1419; - text-shadow: 2px 2px 2px rgba(0, 0, 0, 0.6); - } - 100% { - color: #0f1419; - text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.6); - } -} - -.label-icon { - font-size: 1.2em; -} - -.date-input { - background: rgba(255, 255, 255, 0.1); - backdrop-filter: blur(10px); - -webkit-backdrop-filter: blur(10px); - border: 1px solid rgba(255, 255, 255, 0.3); - border-radius: 15px; - padding: 12px 16px; - color: #0a0f14; - font-size: 1em; - font-weight: 500; - transition: all 0.3s ease; - box-shadow: - 0 4px 15px rgba(31, 38, 135, 0.1), - inset 0 1px 0 rgba(255, 255, 255, 0.2); - animation: inputColorShift 25s ease infinite; -} - -@keyframes inputColorShift { - 0% { - background: rgba(255, 255, 255, 0.1); - border-color: rgba(255, 255, 255, 0.3); - color: #0a0f14; - } - 25% { - background: rgba(255, 255, 255, 0.2); - border-color: rgba(255, 255, 255, 0.4); - color: #1a252f; - } - 50% { - background: rgba(255, 255, 255, 0.15); - border-color: rgba(255, 255, 255, 0.35); - color: #2c3e50; - } - 75% { - background: rgba(255, 255, 255, 0.18); - border-color: rgba(255, 255, 255, 0.38); - color: #0a0f14; - } - 100% { - background: rgba(255, 255, 255, 0.1); - border-color: rgba(255, 255, 255, 0.3); - color: #0a0f14; - } -} - -.date-input:focus { - outline: none; - border-color: rgba(255, 255, 255, 0.5); - background: rgba(255, 255, 255, 0.15); - box-shadow: - 0 6px 20px rgba(31, 38, 135, 0.2), - inset 0 1px 0 rgba(255, 255, 255, 0.3), - 0 0 0 3px rgba(255, 255, 255, 0.1); - transform: translateY(-2px); -} - -.date-input::-webkit-calendar-picker-indicator { - filter: invert(1); - opacity: 0.8; - cursor: pointer; -} - -.query-btn { - background: rgba(255, 255, 255, 0.15); - backdrop-filter: blur(15px); - -webkit-backdrop-filter: blur(15px); - color: #0a0f14; - border: 1px solid rgba(255, 255, 255, 0.3); - padding: 12px 28px; - border-radius: 20px; - cursor: pointer; - font-size: 1em; - font-weight: 600; - transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94); - display: flex; - align-items: center; - gap: 8px; - position: relative; - overflow: hidden; - text-shadow: 0 1px 3px rgba(0, 0, 0, 0.5); - box-shadow: - 0 4px 15px rgba(31, 38, 135, 0.2), - inset 0 1px 0 rgba(255, 255, 255, 0.3); - animation: buttonColorShift 25s ease infinite; -} - -@keyframes buttonColorShift { - 0% { - background: rgba(255, 255, 255, 0.15); - border-color: rgba(255, 255, 255, 0.3); - color: #0a0f14; - } - 25% { - background: rgba(255, 255, 255, 0.25); - border-color: rgba(255, 255, 255, 0.4); - color: #1a252f; - } - 50% { - background: rgba(255, 255, 255, 0.2); - border-color: rgba(255, 255, 255, 0.35); - color: #2c3e50; - } - 75% { - background: rgba(255, 255, 255, 0.22); - border-color: rgba(255, 255, 255, 0.38); - color: #0a0f14; - } - 100% { - background: rgba(255, 255, 255, 0.15); - border-color: rgba(255, 255, 255, 0.3); - color: #0a0f14; - } -} - -.query-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.6s ease; -} - -.query-btn:hover::before { - left: 100%; -} - -.query-btn:hover { - background: rgba(255, 255, 255, 0.2); - border-color: rgba(255, 255, 255, 0.4); - transform: translateY(-3px); - box-shadow: - 0 8px 25px rgba(31, 38, 135, 0.3), - inset 0 1px 0 rgba(255, 255, 255, 0.4); -} - -.btn-icon { - font-size: 1.2em; - transition: transform 0.3s ease; -} - -.query-btn:hover .btn-icon { - transform: scale(1.1) rotate(5deg); -} - -.update-time { - display: flex; - align-items: center; - justify-content: center; - gap: 8px; - color: #1a252f; - font-size: 1em; - padding: 10px 20px; - background: rgba(255, 255, 255, 0.08); - backdrop-filter: blur(8px); - -webkit-backdrop-filter: blur(8px); - border-radius: 20px; - border: 1px solid rgba(255, 255, 255, 0.15); - display: inline-flex; - text-shadow: 0 1px 3px rgba(0, 0, 0, 0.4); - font-weight: 600; -} - -.time-icon { - font-size: 1.2em; - animation: clockTick 2s infinite; -} - -@keyframes clockTick { - 0%, 50% { transform: rotate(0deg); } - 25% { transform: rotate(15deg); } - 75% { transform: rotate(-15deg); } -} - -/* 玻璃拟态加载动画 */ -.loading { - text-align: center; - padding: 60px 40px; - background: rgba(255, 255, 255, 0.1); - backdrop-filter: blur(25px); - -webkit-backdrop-filter: blur(25px); - border-radius: 25px; - margin-bottom: 25px; - border: 1px solid rgba(255, 255, 255, 0.2); - box-shadow: - 0 8px 32px 0 rgba(31, 38, 135, 0.2), - inset 0 1px 0 rgba(255, 255, 255, 0.3); -} - -.loading-content { - display: flex; - flex-direction: column; - align-items: center; - gap: 25px; -} - -.glass-spinner { - width: 60px; - height: 60px; - border: 4px solid rgba(255, 255, 255, 0.1); - border-top: 4px solid rgba(255, 255, 255, 0.8); - border-radius: 50%; - animation: glassSpinnerRotate 1.5s linear infinite; - position: relative; - backdrop-filter: blur(5px); - -webkit-backdrop-filter: blur(5px); -} - -.glass-spinner::before { - content: ''; - position: absolute; - top: -4px; - left: -4px; - right: -4px; - bottom: -4px; - border: 2px solid rgba(255, 255, 255, 0.05); - border-top: 2px solid rgba(255, 255, 255, 0.3); - border-radius: 50%; - animation: glassSpinnerRotate 2s linear infinite reverse; -} - -@keyframes glassSpinnerRotate { - 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: mysticalPulse 2s ease-in-out infinite alternate; - filter: drop-shadow(0 0 10px rgba(255, 255, 255, 0.5)); -} - -@keyframes mysticalPulse { - 0% { - transform: scale(1); - filter: drop-shadow(0 0 10px rgba(255, 255, 255, 0.5)); - } - 100% { - transform: scale(1.1); - filter: drop-shadow(0 0 20px rgba(255, 255, 255, 0.8)); - } -} - -.loading-text p { - font-size: 1.2em; - color: rgba(255, 255, 255, 0.9); - font-weight: 600; - margin: 0; - text-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); -} - -.loading-dots { - display: flex; - gap: 8px; -} - -.loading-dots span { - width: 10px; - height: 10px; - background: rgba(255, 255, 255, 0.7); - border-radius: 50%; - animation: glassDotsFloat 1.4s ease-in-out infinite both; - backdrop-filter: blur(2px); - -webkit-backdrop-filter: blur(2px); - box-shadow: 0 2px 8px rgba(255, 255, 255, 0.3); -} - -.loading-dots span:nth-child(1) { animation-delay: -0.32s; } -.loading-dots span:nth-child(2) { animation-delay: -0.16s; } -.loading-dots span:nth-child(3) { animation-delay: 0s; } - -@keyframes glassDotsFloat { - 0%, 80%, 100% { - transform: scale(0.8); - opacity: 0.5; - } - 40% { - transform: scale(1.2); - opacity: 1; - } -} - -/* 农历信息展示 */ -.lunar-info { - display: grid; - gap: 25px; - animation: infoFadeIn 0.8s ease-out; -} - -@keyframes infoFadeIn { - from { - opacity: 0; - transform: translateY(30px); - } - to { - opacity: 1; - transform: translateY(0); - } -} - -.info-card { - background: rgba(255, 255, 255, 0.12); - backdrop-filter: blur(20px); - -webkit-backdrop-filter: blur(20px); - border: 1px solid rgba(255, 255, 255, 0.2); - border-radius: 20px; - padding: 30px; - position: relative; - overflow: hidden; - transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94); - box-shadow: - 0 8px 32px 0 rgba(31, 38, 135, 0.15), - inset 0 1px 0 rgba(255, 255, 255, 0.3); -} - -.info-card::before { - content: ''; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 3px; - background: linear-gradient(90deg, - rgba(255, 255, 255, 0.3), - rgba(255, 255, 255, 0.6), - rgba(255, 255, 255, 0.3) - ); - transform: scaleX(0); - transition: transform 0.4s ease; -} - -.info-card:hover::before { - transform: scaleX(1); -} - -.info-card:hover { - transform: translateY(-5px); - background: rgba(255, 255, 255, 0.15); - border-color: rgba(255, 255, 255, 0.3); - box-shadow: - 0 12px 40px 0 rgba(31, 38, 135, 0.2), - inset 0 1px 0 rgba(255, 255, 255, 0.4); -} - -.card-header { - display: flex; - align-items: center; - gap: 15px; - margin-bottom: 20px; -} - -.card-icon { - font-size: 2.5em; - animation: cardIconFloat 3s ease-in-out infinite; -} - -@keyframes cardIconFloat { - 0%, 100% { transform: translateY(0) rotate(0deg); } - 50% { transform: translateY(-5px) rotate(5deg); } -} - -.card-title { - font-size: 1.5em; - font-weight: 700; - color: #0a0f14; - text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6); -} - -.card-content { - display: grid; - gap: 15px; -} - -.info-item { - display: flex; - align-items: center; - gap: 12px; - padding: 15px; - background: rgba(255, 255, 255, 0.08); - backdrop-filter: blur(10px); - -webkit-backdrop-filter: blur(10px); - border-radius: 15px; - border: 1px solid rgba(255, 255, 255, 0.15); - transition: all 0.3s ease; -} - -.info-item:hover { - background: rgba(255, 255, 255, 0.12); - transform: scale(1.02); -} - -.item-icon { - font-size: 1.3em; - min-width: 30px; - text-align: center; -} - -.item-label { - font-weight: 600; - color: #1a252f; - min-width: 80px; - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); -} - -.item-value { - font-weight: 700; - color: #0a0f14; - font-size: 1.1em; - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); -} - -/* 错误信息 */ -.error-message { - text-align: center; - padding: 60px 40px; - background: rgba(255, 255, 255, 0.1); - backdrop-filter: blur(25px); - -webkit-backdrop-filter: blur(25px); - border-radius: 25px; - border: 1px solid rgba(255, 255, 255, 0.2); - box-shadow: - 0 8px 32px 0 rgba(31, 38, 135, 0.2), - inset 0 1px 0 rgba(255, 255, 255, 0.3); -} - -.error-content { - display: flex; - flex-direction: column; - align-items: center; - gap: 25px; -} - -.error-icon { - font-size: 4em; - animation: errorFloat 2s ease-in-out infinite alternate; - filter: drop-shadow(0 0 10px rgba(255, 255, 255, 0.3)); -} - -@keyframes errorFloat { - 0% { transform: translateY(0) rotate(-5deg); } - 100% { transform: translateY(-10px) rotate(5deg); } -} - -.error-content h3 { - font-size: 1.6em; - color: #0a0f14; - margin: 0; - font-weight: 700; - text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6); -} - -.error-content p { - color: #1a252f; - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4); - font-size: 1.1em; - margin: 0; - line-height: 1.6; - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); -} - -.retry-btn { - background: rgba(255, 255, 255, 0.15); - backdrop-filter: blur(15px); - -webkit-backdrop-filter: blur(15px); - color: #0a0f14; - border: 1px solid rgba(255, 255, 255, 0.3); - padding: 12px 25px; - border-radius: 20px; - cursor: pointer; - font-size: 1em; - font-weight: 600; - transition: all 0.4s ease; - display: inline-flex; - align-items: center; - gap: 8px; - text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6); - box-shadow: - 0 4px 15px rgba(31, 38, 135, 0.2), - inset 0 1px 0 rgba(255, 255, 255, 0.3); -} - -.retry-btn:hover { - background: rgba(255, 255, 255, 0.2); - border-color: rgba(255, 255, 255, 0.4); - transform: translateY(-2px); - box-shadow: - 0 6px 20px rgba(31, 38, 135, 0.3), - inset 0 1px 0 rgba(255, 255, 255, 0.4); -} - -.retry-btn span { - font-size: 1.1em; - transition: transform 0.3s ease; -} - -.retry-btn:hover span { - transform: rotate(180deg); -} - -/* 功能提示 */ -.feature-tips { - margin-top: 40px; -} - -.tip-card { - background: rgba(255, 255, 255, 0.1); - backdrop-filter: blur(20px); - -webkit-backdrop-filter: blur(20px); - border: 1px solid rgba(255, 255, 255, 0.2); - border-radius: 20px; - padding: 30px; - text-align: center; - box-shadow: - 0 8px 32px 0 rgba(31, 38, 135, 0.15), - inset 0 1px 0 rgba(255, 255, 255, 0.3); -} - -.tip-icon { - font-size: 3em; - margin-bottom: 15px; - animation: tipBlink 3s ease-in-out infinite; -} - -@keyframes tipBlink { - 0%, 100% { opacity: 1; transform: scale(1); } - 50% { opacity: 0.7; transform: scale(1.05); } -} - -.tip-card h3 { - font-size: 1.4em; - font-weight: 700; - color: #0a0f14; - margin-bottom: 20px; - text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6); -} - -.tip-card ul { - list-style: none; - display: grid; - gap: 12px; - text-align: left; -} - -.tip-card li { - color: #1a252f; - font-size: 1em; - padding: 10px 15px; - background: rgba(255, 255, 255, 0.08); - backdrop-filter: blur(5px); - -webkit-backdrop-filter: blur(5px); - border-radius: 10px; - border: 1px solid rgba(255, 255, 255, 0.15); - transition: all 0.3s ease; - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4); -} - -.tip-card li:hover { - background: rgba(255, 255, 255, 0.12); - transform: translateX(5px); -} - -/* 平板端适配 (768px - 1024px) */ -@media (min-width: 768px) and (max-width: 1024px) { - .container { - padding: 25px; - } - - .header { - padding: 35px 25px; - } - - .header-icon { - font-size: 3.5em; - } - - .title { - font-size: 2.8em; - letter-spacing: 1.5px; - } - - .subtitle { - font-size: 1.2em; - } - - .date-selector { - gap: 15px; - } - - .input-group { - min-width: 180px; - } - - .lunar-info { - grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); - gap: 20px; - } - - .info-card { - padding: 25px; - } -} - -/* 电脑端适配 (1025px+) */ -@media (min-width: 1025px) { - .container { - padding: 40px; - } - - .header { - padding: 50px 40px; - margin-bottom: 50px; - } - - .header-icon { - font-size: 4.5em; - } - - .title { - font-size: 3.8em; - letter-spacing: 3px; - } - - .subtitle { - font-size: 1.4em; - } - - .date-selector { - gap: 25px; - } - - .input-group { - min-width: 220px; - } - - .date-input { - padding: 14px 18px; - font-size: 1.05em; - } - - .query-btn { - padding: 14px 32px; - font-size: 1.05em; - } - - .lunar-info { - grid-template-columns: repeat(auto-fit, minmax(500px, 1fr)); - gap: 30px; - } - - .info-card { - padding: 35px; - } - - .card-title { - font-size: 1.6em; - } - - .item-label { - min-width: 100px; - } - - .item-value { - font-size: 1.15em; - } - - /* 电脑端特殊效果 */ - .info-card:hover { - transform: translateY(-8px) scale(1.02); - } -} - -/* 手机端适配 (767px以下) */ -@media (max-width: 767px) { - .container { - padding: 15px; - } - - .header { - padding: 25px 20px; - margin-bottom: 25px; - } - - .header-icon { - font-size: 2.8em; - } - - .title { - font-size: 2.2em; - letter-spacing: 1px; - } - - .subtitle { - font-size: 1em; - } - - .date-selector { - flex-direction: column; - gap: 15px; - align-items: center; - } - - .input-group { - width: 100%; - max-width: 300px; - min-width: auto; - } - - .date-input { - padding: 10px 14px; - font-size: 0.95em; - } - - .query-btn { - padding: 10px 24px; - font-size: 0.95em; - width: 100%; - max-width: 200px; - justify-content: center; - } - - .update-time { - font-size: 0.9em; - padding: 8px 16px; - } - - .info-card { - padding: 20px; - border-radius: 15px; - } - - .card-header { - gap: 12px; - margin-bottom: 15px; - } - - .card-icon { - font-size: 2em; - } - - .card-title { - font-size: 1.3em; - } - - .info-item { - padding: 12px; - flex-direction: column; - align-items: flex-start; - gap: 8px; - } - - .item-icon { - font-size: 1.2em; - } - - .item-label { - min-width: auto; - font-size: 0.9em; - } - - .item-value { - font-size: 1em; - } - - .tip-card { - padding: 20px; - } - - .tip-card ul { - gap: 10px; - } - - .tip-card li { - padding: 8px 12px; - font-size: 0.9em; - } - - /* 手机端性能优化 - 减少动画 */ - .title { - animation: none; - } - - .subtitle { - animation: none; - } - - .input-label { - animation: none; - } - - .date-input { - animation: none; - } - - .query-btn { - animation: none; - } - - .card-icon { - animation: none; - } - - .tip-icon { - animation: none; - } -} - -/* 超小屏幕适配 (480px以下) */ -@media (max-width: 480px) { - .container { - padding: 12px; - } - - .header { - padding: 20px 15px; - margin-bottom: 20px; - } - - .header-icon { - font-size: 2.5em; - } - - .title { - font-size: 1.9em; - letter-spacing: 0.5px; - } - - .subtitle { - font-size: 0.95em; - } - - .date-selector { - gap: 12px; - } - - .input-group { - max-width: 280px; - } - - .date-input { - padding: 8px 12px; - font-size: 0.9em; - } - - .query-btn { - padding: 8px 20px; - font-size: 0.9em; - max-width: 180px; - } - - .update-time { - font-size: 0.85em; - padding: 6px 12px; - flex-direction: column; - gap: 4px; - } - - .lunar-info { - gap: 15px; - } - - .info-card { - padding: 18px 15px; - border-radius: 12px; - } - - .card-header { - gap: 10px; - margin-bottom: 12px; - } - - .card-icon { - font-size: 1.8em; - } - - .card-title { - font-size: 1.2em; - } - - .info-item { - padding: 10px; - gap: 6px; - } - - .item-icon { - font-size: 1.1em; - } - - .item-label { - font-size: 0.85em; - } - - .item-value { - font-size: 0.95em; - } - - .tip-card { - padding: 15px; - } - - .tip-icon { - font-size: 2.5em; - } - - .tip-card h3 { - font-size: 1.2em; - } - - .tip-card li { - padding: 6px 10px; - font-size: 0.85em; - } - - /* 超小屏幕性能优化 */ - .info-card { - transition: transform 0.2s ease, background 0.2s ease; - } - - .info-card::before { - display: none; - } - - /* 禁用复杂动画以提升性能 */ - .title { - animation: none; - } - - .subtitle { - animation: none; - } - - .input-label { - animation: none; - } - - .date-input { - animation: none; - } - - .query-btn { - animation: none; - } - - .card-icon { - animation: none; - } - - .tip-icon { - animation: none; - } - - .loading-content { - gap: 15px; - } - - .loading-emoji { - font-size: 2em; - } - - .error-icon { - font-size: 3em; - } -} - -/* 时辰宜忌特殊样式 */ -.hours-card { - grid-column: 1 / -1; /* 占满整行 */ -} - -.hours-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); - gap: 15px; - margin-top: 15px; -} - -.hour-item { - background: rgba(255, 255, 255, 0.1); - backdrop-filter: blur(10px); - border: 1px solid rgba(255, 255, 255, 0.2); - border-radius: 12px; - padding: 12px; - transition: all 0.3s ease; -} - -.hour-item:hover { - background: rgba(255, 255, 255, 0.15); - transform: translateY(-2px); - box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1); -} - -.hour-name { - font-size: 14px; - font-weight: 600; - color: #2c3e50; - text-align: center; - margin-bottom: 8px; - padding: 4px 8px; - background: rgba(255, 255, 255, 0.8); - border-radius: 6px; - text-shadow: 0 1px 2px rgba(255, 255, 255, 0.5); - border: 1px solid rgba(255, 255, 255, 0.9); -} - -.hour-content { - font-size: 12px; - line-height: 1.4; -} - -.hour-recommends, -.hour-avoids { - margin: 4px 0; -} - -.hour-label { - font-weight: 600; - color: #ffffff; - margin-right: 4px; -} - -.hour-recommends .hour-label { - color: #4ade80; -} - -.hour-avoids .hour-label { - color: #f87171; -} - -.hour-text { - color: rgba(255, 255, 255, 0.9); -} - -/* 时辰宜忌响应式优化 */ -@media (max-width: 768px) { - .hours-grid { - grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); - gap: 10px; - } - - .hour-item { - padding: 8px; - } - - .hour-name { - font-size: 12px; - margin-bottom: 6px; - } - - .hour-content { - font-size: 11px; - } -} diff --git a/frontend/60sapi/实用功能/农历信息/index.html b/frontend/60sapi/实用功能/农历信息/index.html deleted file mode 100755 index 6744ddec..00000000 --- a/frontend/60sapi/实用功能/农历信息/index.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - 🌙 农历信息查询 - - - - - -
- - -
-
-
-
-
-
-
-
- - -
-
-
-
-
-
-
-
-
-
-
- - -
-
-
-
-
-
-
-
-
-
- -
-
-
🏮
-

🌙 农历信息查询 📅

-

传统文化 · 时光转换 · 节气查询

- -
-
- - -
- -
- -
- - 等待查询... -
-
- - - - - - - - - - - diff --git a/frontend/60sapi/实用功能/农历信息/js/script.js b/frontend/60sapi/实用功能/农历信息/js/script.js deleted file mode 100755 index 262c1e91..00000000 --- a/frontend/60sapi/实用功能/农历信息/js/script.js +++ /dev/null @@ -1,481 +0,0 @@ -// API接口列表 -const API_ENDPOINTS = [ - "https://60s.api.shumengya.top", -]; - -// 当前使用的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 = ` -
-
-
📅
-
公历信息
-
-
-
-
🗓️
-
公历日期
-
${lunarData.solar.year}年${String(lunarData.solar.month).padStart(2, '0')}月${String(lunarData.solar.day).padStart(2, '0')}日
-
-
-
🌍
-
星期
-
${lunarData.solar.week_desc}
-
-
-
🍂
-
季节
-
${lunarData.solar.season_name_desc}
-
-
-
-
星座
-
${lunarData.constellation.name}
-
-
-
- -
-
-
🌙
-
农历信息
-
-
-
-
🏮
-
农历日期
-
${lunarData.lunar.desc_short}
-
-
-
🐲
-
生肖年
-
${lunarData.zodiac.year}年
-
-
-
☯️
-
天干地支
-
${lunarData.sixty_cycle.year.name}
-
-
-
🌙
-
月相
-
${lunarData.phase.name}
-
-
-
- -
-
-
🌾
-
节气节日
-
-
-
-
🌱
-
当前节气
-
${lunarData.term.stage ? lunarData.term.stage.name : '无节气'}
-
-
-
🎉
-
法定假日
-
${lunarData.legal_holiday ? lunarData.legal_holiday.name : '无假日'}
-
-
-
🎊
-
传统节日
-
${lunarData.festival.both_desc || '无特殊节日'}
-
-
-
📊
-
一年第几天
-
第${lunarData.stats.day_of_year}天
-
-
-
- -
-
-
-
时辰干支
-
-
-
-
🕐
-
当前时辰
-
${lunarData.lunar.hour_desc}
-
-
-
☯️
-
时辰干支
-
${lunarData.sixty_cycle.hour.name}
-
-
-
🐾
-
时辰生肖
-
${lunarData.zodiac.hour}
-
-
-
🎵
-
纳音
-
${lunarData.nayin.hour}
-
-
-
- -
-
-
📖
-
黄历宜忌
-
-
-
-
-
-
${formatTabooText(lunarData.taboo.day.recommends)}
-
-
-
-
-
${formatTabooText(lunarData.taboo.day.avoids)}
-
-
-
🕐
-
时辰宜
-
${formatTabooText(lunarData.taboo.hour.recommends)}
-
-
-
🚫
-
时辰忌
-
${formatTabooText(lunarData.taboo.hour.avoids)}
-
-
-
- -
-
-
🌟
-
运势财运
-
-
-
-
🍀
-
今日运势
-
${lunarData.fortune.today_luck}
-
-
-
💼
-
事业运
-
${lunarData.fortune.career}
-
-
-
💰
-
财运
-
${lunarData.fortune.money}
-
-
-
💖
-
感情运
-
${lunarData.fortune.love}
-
-
-
- -
-
-
📈
-
年度统计
-
-
-
-
📊
-
年度进度
-
${lunarData.stats.percents_formatted.year}
-
-
-
📅
-
本月进度
-
${lunarData.stats.percents_formatted.month}
-
-
-
🗓️
-
本周第几天
-
第${lunarData.stats.week_of_month}周
-
-
-
-
今日进度
-
${lunarData.stats.percents_formatted.day}
-
-
-
- - ${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 => ` -
-
${hour.hour}
-
-
- 宜: - ${formatTabooText(hour.recommends) || '无'} -
-
- 忌: - ${formatTabooText(hour.avoids) || '无'} -
-
-
- `).join(''); - - return ` -
-
-
-
十二时辰宜忌
-
-
-
- ${hourCards} -
-
-
- `; -} - -// 更新查询时间 -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(); - } -}); diff --git a/frontend/60sapi/实用功能/农历信息/接口集合.json b/frontend/60sapi/实用功能/农历信息/接口集合.json deleted file mode 100755 index 547b2771..00000000 --- a/frontend/60sapi/实用功能/农历信息/接口集合.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "https://60s.api.shumengya.top" -] diff --git a/frontend/60sapi/实用功能/农历信息/返回接口.json b/frontend/60sapi/实用功能/农历信息/返回接口.json deleted file mode 100755 index 910981d4..00000000 --- a/frontend/60sapi/实用功能/农历信息/返回接口.json +++ /dev/null @@ -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": "一年最冷" - } - ] - } - } -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/哈希解压压缩/css/style.css b/frontend/60sapi/实用功能/哈希解压压缩/css/style.css deleted file mode 100755 index 4b94a03d..00000000 --- a/frontend/60sapi/实用功能/哈希解压压缩/css/style.css +++ /dev/null @@ -1,561 +0,0 @@ -/* Reset and Base Styles */ -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -body { - font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - min-height: 100vh; - color: #333; - overflow-x: hidden; -} - -.container { - max-width: 1400px; - margin: 0 auto; - padding: 20px; - position: relative; -} - -/* Header Styles */ -.header { - text-align: center; - margin-bottom: 40px; - position: relative; - z-index: 2; -} - -.header-content { - background: rgba(255, 255, 255, 0.1); - backdrop-filter: blur(20px); - border-radius: 24px; - padding: 40px; - border: 1px solid rgba(255, 255, 255, 0.2); - box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1); - position: relative; - overflow: hidden; -} - -.header-content::before { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: linear-gradient(45deg, rgba(255, 255, 255, 0.1) 0%, transparent 50%, rgba(255, 255, 255, 0.1) 100%); - animation: shimmer 3s ease-in-out infinite; -} - -@keyframes shimmer { - 0%, 100% { transform: translateX(-100%); } - 50% { transform: translateX(100%); } -} - -.logo { - display: flex; - align-items: center; - justify-content: center; - gap: 15px; - margin-bottom: 15px; -} - -.logo i { - font-size: 48px; - background: linear-gradient(45deg, #ff6b6b, #4ecdc4); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; - animation: pulse 2s ease-in-out infinite; -} - -@keyframes pulse { - 0%, 100% { transform: scale(1); } - 50% { transform: scale(1.1); } -} - -.logo h1 { - font-size: 42px; - font-weight: 700; - color: white; - text-shadow: 0 4px 8px rgba(0, 0, 0, 0.3); -} - -.subtitle { - font-size: 18px; - color: rgba(255, 255, 255, 0.9); - font-weight: 400; - letter-spacing: 0.5px; -} - -/* Floating Shapes */ -.header-decoration { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - pointer-events: none; - z-index: 1; -} - -.floating-shapes { - position: relative; - width: 100%; - height: 100%; -} - -.shape { - position: absolute; - border-radius: 50%; - background: linear-gradient(45deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.05)); - animation: float 6s ease-in-out infinite; -} - -.shape-1 { - width: 80px; - height: 80px; - top: 10%; - left: 10%; - animation-delay: 0s; -} - -.shape-2 { - width: 60px; - height: 60px; - top: 20%; - right: 15%; - animation-delay: 2s; -} - -.shape-3 { - width: 100px; - height: 100px; - bottom: 15%; - left: 20%; - animation-delay: 4s; -} - -@keyframes float { - 0%, 100% { transform: translateY(0px) rotate(0deg); } - 33% { transform: translateY(-20px) rotate(120deg); } - 66% { transform: translateY(10px) rotate(240deg); } -} - -/* Input Section */ -.input-section { - margin-bottom: 40px; -} - -.input-card { - background: rgba(255, 255, 255, 0.95); - backdrop-filter: blur(20px); - border-radius: 20px; - padding: 30px; - box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1); - border: 1px solid rgba(255, 255, 255, 0.3); - transition: all 0.3s ease; -} - -.input-card:hover { - transform: translateY(-5px); - box-shadow: 0 30px 60px rgba(0, 0, 0, 0.15); -} - -.card-header { - display: flex; - align-items: center; - gap: 12px; - margin-bottom: 20px; -} - -.card-header i { - font-size: 24px; - color: #667eea; -} - -.card-header h2 { - font-size: 24px; - font-weight: 600; - color: #333; -} - -.input-wrapper { - position: relative; -} - -#inputText { - width: 100%; - padding: 20px; - border: 2px solid #e1e5e9; - border-radius: 12px; - font-size: 16px; - font-family: inherit; - resize: vertical; - transition: all 0.3s ease; - background: rgba(255, 255, 255, 0.8); - backdrop-filter: blur(10px); -} - -#inputText:focus { - outline: none; - border-color: #667eea; - box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1); - background: rgba(255, 255, 255, 0.95); -} - -.input-actions { - display: flex; - gap: 15px; - margin-top: 20px; - justify-content: flex-end; -} - -/* Button Styles */ -.btn { - padding: 12px 24px; - border: none; - border-radius: 10px; - font-size: 16px; - font-weight: 500; - cursor: pointer; - transition: all 0.3s ease; - display: flex; - align-items: center; - gap: 8px; - text-decoration: none; - position: relative; - overflow: hidden; -} - -.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; -} - -.btn:hover::before { - left: 100%; -} - -.btn-primary { - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - color: white; - box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3); -} - -.btn-primary:hover { - transform: translateY(-2px); - box-shadow: 0 8px 25px rgba(102, 126, 234, 0.4); -} - -.btn-secondary { - background: rgba(255, 255, 255, 0.8); - color: #666; - border: 1px solid #e1e5e9; -} - -.btn-secondary:hover { - background: rgba(255, 255, 255, 0.95); - transform: translateY(-2px); - box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1); -} - -/* Results Section */ -.results-section { - opacity: 0; - transform: translateY(30px); - transition: all 0.5s ease; -} - -.results-section.show { - opacity: 1; - transform: translateY(0); -} - -.results-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); - gap: 30px; -} - -.result-card { - background: rgba(255, 255, 255, 0.95); - backdrop-filter: blur(20px); - border-radius: 20px; - padding: 30px; - box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1); - border: 1px solid rgba(255, 255, 255, 0.3); - transition: all 0.3s ease; - position: relative; - overflow: hidden; -} - -.result-card::before { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - height: 4px; - background: linear-gradient(90deg, #ff6b6b, #4ecdc4, #45b7d1, #96ceb4); -} - -.result-card:hover { - transform: translateY(-5px); - box-shadow: 0 30px 60px rgba(0, 0, 0, 0.15); -} - -.result-card .card-header h3 { - font-size: 20px; - font-weight: 600; - color: #333; -} - -.result-items { - display: flex; - flex-direction: column; - gap: 20px; -} - -.result-item { - position: relative; -} - -.result-item label { - display: block; - font-size: 14px; - font-weight: 500; - color: #666; - margin-bottom: 8px; - text-transform: uppercase; - letter-spacing: 0.5px; -} - -.result-value { - display: flex; - align-items: center; - background: rgba(248, 250, 252, 0.8); - border: 1px solid #e1e5e9; - border-radius: 8px; - padding: 12px 16px; - font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace; - font-size: 14px; - word-break: break-all; - position: relative; - transition: all 0.3s ease; -} - -.result-value:hover { - background: rgba(248, 250, 252, 0.95); - border-color: #667eea; -} - -.result-value .placeholder { - color: #999; - font-style: italic; -} - -.copy-btn { - background: none; - border: none; - color: #667eea; - cursor: pointer; - padding: 8px; - border-radius: 6px; - transition: all 0.3s ease; - margin-left: auto; - flex-shrink: 0; -} - -.copy-btn:hover { - background: rgba(102, 126, 234, 0.1); - color: #5a67d8; -} - -/* Loading Overlay */ -.loading-overlay { - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: rgba(0, 0, 0, 0.5); - backdrop-filter: blur(5px); - display: flex; - align-items: center; - justify-content: center; - z-index: 1000; - opacity: 0; - visibility: hidden; - transition: all 0.3s ease; -} - -.loading-overlay.show { - opacity: 1; - visibility: visible; -} - -.loading-spinner { - text-align: center; - color: white; -} - -.spinner { - width: 50px; - height: 50px; - border: 4px solid rgba(255, 255, 255, 0.3); - border-top: 4px solid white; - border-radius: 50%; - animation: spin 1s linear infinite; - margin: 0 auto 20px; -} - -@keyframes spin { - 0% { transform: rotate(0deg); } - 100% { transform: rotate(360deg); } -} - -/* Toast Notification */ -.toast { - position: fixed; - bottom: 30px; - right: 30px; - background: linear-gradient(135deg, #4ecdc4, #44a08d); - color: white; - padding: 16px 24px; - border-radius: 12px; - box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2); - display: flex; - align-items: center; - gap: 10px; - transform: translateX(400px); - transition: all 0.3s ease; - z-index: 1001; -} - -.toast.show { - transform: translateX(0); -} - -.toast i { - font-size: 18px; -} - -/* Responsive Design */ -@media (max-width: 768px) { - .container { - padding: 15px; - } - - .header-content { - padding: 30px 20px; - } - - .logo h1 { - font-size: 32px; - } - - .logo i { - font-size: 36px; - } - - .results-grid { - grid-template-columns: 1fr; - gap: 20px; - } - - .input-actions { - flex-direction: column; - } - - .btn { - justify-content: center; - } - - .toast { - bottom: 20px; - right: 20px; - left: 20px; - transform: translateY(100px); - } - - .toast.show { - transform: translateY(0); - } -} - -@media (max-width: 480px) { - .input-card, - .result-card { - padding: 20px; - } - - .card-header h2, - .card-header h3 { - font-size: 18px; - } - - .result-value { - font-size: 12px; - padding: 10px 12px; - } -} - -/* Animation Classes */ -.fade-in { - animation: fadeIn 0.5s ease-in-out; -} - -@keyframes fadeIn { - from { - opacity: 0; - transform: translateY(20px); - } - to { - opacity: 1; - transform: translateY(0); - } -} - -.slide-in { - animation: slideIn 0.3s ease-out; -} - -@keyframes slideIn { - from { - transform: translateX(-20px); - opacity: 0; - } - to { - transform: translateX(0); - opacity: 1; - } -} - -/* Custom Scrollbar */ -::-webkit-scrollbar { - width: 8px; -} - -::-webkit-scrollbar-track { - background: rgba(255, 255, 255, 0.1); - border-radius: 4px; -} - -::-webkit-scrollbar-thumb { - background: rgba(255, 255, 255, 0.3); - border-radius: 4px; -} - -::-webkit-scrollbar-thumb:hover { - background: rgba(255, 255, 255, 0.5); -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/哈希解压压缩/index.html b/frontend/60sapi/实用功能/哈希解压压缩/index.html deleted file mode 100755 index 5859a369..00000000 --- a/frontend/60sapi/实用功能/哈希解压压缩/index.html +++ /dev/null @@ -1,212 +0,0 @@ - - - - - - 多功能哈希工具 - Hash Toolkit - - - - - -
- -
-
- -

多功能哈希、编码与压缩工具

-
-
-
-
-
-
-
-
-
- - -
- -
-
-
- -

输入内容

-
-
- -
- - -
-
-
-
- - -
-
- -
-
- -

哈希算法

-
-
-
- -
- 等待处理... - -
-
-
- -
- 等待处理... - -
-
-
- -
- 等待处理... - -
-
-
- -
- 等待处理... - -
-
-
-
- - -
-
- -

编码转换

-
-
-
- -
- 等待处理... - -
-
-
- -
- 等待处理... - -
-
-
- -
- 等待处理... - -
-
-
- -
- 等待处理... - -
-
-
-
- - -
-
- -

压缩算法

-
-
-
- -
- 等待处理... - -
-
-
- -
- 等待处理... - -
-
-
- -
- 等待处理... - -
-
-
-
-
-
-
- - -
-
-
-

正在处理中...

-
-
- - -
- - 复制成功! -
-
- - - - \ No newline at end of file diff --git a/frontend/60sapi/实用功能/哈希解压压缩/js/script.js b/frontend/60sapi/实用功能/哈希解压压缩/js/script.js deleted file mode 100755 index 6f846356..00000000 --- a/frontend/60sapi/实用功能/哈希解压压缩/js/script.js +++ /dev/null @@ -1,394 +0,0 @@ -// API配置 -const API_BASE_URL = 'https://60s.api.shumengya.top/v2/hash'; - -// DOM元素 -const elements = { - inputText: document.getElementById('inputText'), - processBtn: document.getElementById('processBtn'), - clearBtn: document.getElementById('clearBtn'), - resultsSection: document.getElementById('resultsSection'), - loadingOverlay: document.getElementById('loadingOverlay'), - toast: document.getElementById('toast'), - toastMessage: document.getElementById('toastMessage') -}; - -// 结果元素映射 -const resultElements = { - md5: document.getElementById('md5Result'), - sha1: document.getElementById('sha1Result'), - sha256: document.getElementById('sha256Result'), - sha512: document.getElementById('sha512Result'), - base64Encode: document.getElementById('base64EncodeResult'), - base64Decode: document.getElementById('base64DecodeResult'), - urlEncode: document.getElementById('urlEncodeResult'), - urlDecode: document.getElementById('urlDecodeResult'), - gzipCompress: document.getElementById('gzipCompressResult'), - deflateCompress: document.getElementById('deflateCompressResult'), - brotliCompress: document.getElementById('brotliCompressResult') -}; - -// 初始化 -document.addEventListener('DOMContentLoaded', function() { - initializeEventListeners(); - addInputAnimation(); -}); - -// 事件监听器初始化 -function initializeEventListeners() { - // 处理按钮点击 - elements.processBtn.addEventListener('click', handleProcess); - - // 清空按钮点击 - elements.clearBtn.addEventListener('click', handleClear); - - // 输入框回车键 - elements.inputText.addEventListener('keydown', function(e) { - if (e.ctrlKey && e.key === 'Enter') { - handleProcess(); - } - }); - - // 复制按钮事件委托 - document.addEventListener('click', function(e) { - if (e.target.closest('.copy-btn')) { - const copyBtn = e.target.closest('.copy-btn'); - const targetId = copyBtn.getAttribute('data-target'); - const targetElement = document.getElementById(targetId); - const textContent = targetElement.textContent.trim(); - - if (textContent && textContent !== '等待处理...' && textContent !== '处理失败') { - copyToClipboard(textContent); - } - } - }); - - // 输入框实时验证 - elements.inputText.addEventListener('input', function() { - const hasContent = this.value.trim().length > 0; - elements.processBtn.disabled = !hasContent; - - if (hasContent) { - elements.processBtn.classList.remove('disabled'); - } else { - elements.processBtn.classList.add('disabled'); - } - }); -} - -// 添加输入动画效果 -function addInputAnimation() { - elements.inputText.addEventListener('focus', function() { - this.parentElement.classList.add('focused'); - }); - - elements.inputText.addEventListener('blur', function() { - this.parentElement.classList.remove('focused'); - }); -} - -// 处理主要功能 -async function handleProcess() { - const inputValue = elements.inputText.value.trim(); - - if (!inputValue) { - showToast('请输入要处理的内容', 'error'); - return; - } - - // 显示加载状态 - showLoading(true); - resetResults(); - - try { - // 调用API - const response = await fetch(`${API_BASE_URL}?content=${encodeURIComponent(inputValue)}`); - - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } - - const data = await response.json(); - - if (data.code === 200 && data.data) { - displayResults(data.data); - showResultsSection(); - showToast('处理完成!', 'success'); - } else { - throw new Error(data.message || '处理失败'); - } - - } catch (error) { - console.error('处理错误:', error); - showToast(`处理失败: ${error.message}`, 'error'); - displayError(); - } finally { - showLoading(false); - } -} - -// 显示结果 -function displayResults(data) { - try { - // 哈希结果 - updateResultElement('md5', data.md5 || '不可用'); - - // SHA系列 - if (data.sha) { - updateResultElement('sha1', data.sha.sha1 || '不可用'); - updateResultElement('sha256', data.sha.sha256 || '不可用'); - updateResultElement('sha512', data.sha.sha512 || '不可用'); - } - - // Base64编码 - if (data.base64) { - updateResultElement('base64Encode', data.base64.encoded || '不可用'); - // BASE64解码:只有当输入本身是BASE64格式时才显示解码结果 - let base64DecodeResult = data.base64.decoded; - if (!base64DecodeResult) { - // 检查输入是否为有效的BASE64格式 - const inputValue = elements.inputText.value.trim(); - const base64Regex = /^[A-Za-z0-9+/]*={0,2}$/; - if (base64Regex.test(inputValue) && inputValue.length % 4 === 0) { - try { - base64DecodeResult = atob(inputValue); - } catch (e) { - base64DecodeResult = '解码失败'; - } - } else { - base64DecodeResult = '输入非BASE64格式'; - } - } - updateResultElement('base64Decode', base64DecodeResult || '不可用'); - } - - // URL编码 - if (data.url) { - updateResultElement('urlEncode', data.url.encoded || '不可用'); - updateResultElement('urlDecode', data.url.decoded || '不可用'); - } - - // 压缩结果(仅显示压缩,不显示解压) - if (data.gzip) { - updateResultElement('gzipCompress', data.gzip.encoded || '不可用'); - } - - if (data.deflate) { - updateResultElement('deflateCompress', data.deflate.encoded || '不可用'); - } - - if (data.brotli) { - updateResultElement('brotliCompress', data.brotli.encoded || '不可用'); - } - - } catch (error) { - console.error('显示结果时出错:', error); - showToast('显示结果时出错', 'error'); - } -} - -// 更新单个结果元素 -function updateResultElement(key, value) { - const element = resultElements[key]; - if (element) { - const textSpan = element.querySelector('span') || element; - textSpan.textContent = value; - textSpan.classList.remove('placeholder'); - - // 添加动画效果 - element.classList.add('slide-in'); - setTimeout(() => { - element.classList.remove('slide-in'); - }, 300); - } -} - -// 重置结果 -function resetResults() { - Object.values(resultElements).forEach(element => { - if (element) { - const textSpan = element.querySelector('span') || element; - textSpan.textContent = '等待处理...'; - textSpan.classList.add('placeholder'); - } - }); -} - -// 显示错误状态 -function displayError() { - Object.values(resultElements).forEach(element => { - if (element) { - const textSpan = element.querySelector('span') || element; - textSpan.textContent = '处理失败'; - textSpan.classList.add('placeholder'); - } - }); -} - -// 显示结果区域 -function showResultsSection() { - elements.resultsSection.classList.add('show'); - - // 平滑滚动到结果区域 - setTimeout(() => { - elements.resultsSection.scrollIntoView({ - behavior: 'smooth', - block: 'start' - }); - }, 100); -} - -// 清空功能 -function handleClear() { - elements.inputText.value = ''; - elements.inputText.focus(); - elements.resultsSection.classList.remove('show'); - resetResults(); - elements.processBtn.disabled = true; - elements.processBtn.classList.add('disabled'); - - showToast('内容已清空', 'info'); -} - -// 复制到剪贴板 -async function copyToClipboard(text) { - try { - if (navigator.clipboard && window.isSecureContext) { - await navigator.clipboard.writeText(text); - } else { - // 降级方案 - const textArea = document.createElement('textarea'); - textArea.value = text; - 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(); - } - - showToast('复制成功!', 'success'); - } catch (error) { - console.error('复制失败:', error); - showToast('复制失败,请手动复制', 'error'); - } -} - -// 显示/隐藏加载状态 -function showLoading(show) { - if (show) { - elements.loadingOverlay.classList.add('show'); - elements.processBtn.disabled = true; - elements.processBtn.innerHTML = ' 处理中...'; - } else { - elements.loadingOverlay.classList.remove('show'); - elements.processBtn.disabled = false; - elements.processBtn.innerHTML = ' 开始处理'; - } -} - -// 显示提示消息 -function showToast(message, type = 'success') { - elements.toastMessage.textContent = message; - - // 设置图标和样式 - const icon = elements.toast.querySelector('i'); - icon.className = getToastIcon(type); - - elements.toast.className = `toast ${type}`; - elements.toast.classList.add('show'); - - // 自动隐藏 - setTimeout(() => { - elements.toast.classList.remove('show'); - }, 3000); -} - -// 获取提示图标 -function getToastIcon(type) { - const icons = { - success: 'fas fa-check-circle', - error: 'fas fa-exclamation-circle', - info: 'fas fa-info-circle', - warning: 'fas fa-exclamation-triangle' - }; - return icons[type] || icons.success; -} - -// 工具函数:防抖 -function debounce(func, wait) { - let timeout; - return function executedFunction(...args) { - const later = () => { - clearTimeout(timeout); - func(...args); - }; - clearTimeout(timeout); - timeout = setTimeout(later, wait); - }; -} - -// 工具函数:节流 -function 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); - } - } -} - -// 添加键盘快捷键支持 -document.addEventListener('keydown', function(e) { - // Ctrl+Enter 处理 - if (e.ctrlKey && e.key === 'Enter') { - e.preventDefault(); - if (!elements.processBtn.disabled) { - handleProcess(); - } - } - - // Escape 清空 - if (e.key === 'Escape') { - handleClear(); - } -}); - -// 页面可见性变化处理 -document.addEventListener('visibilitychange', function() { - if (document.hidden) { - // 页面隐藏时的处理 - console.log('页面已隐藏'); - } else { - // 页面显示时的处理 - console.log('页面已显示'); - } -}); - -// 错误处理 -window.addEventListener('error', function(e) { - console.error('全局错误:', e.error); - showToast('发生未知错误,请刷新页面重试', 'error'); -}); - -// 未处理的Promise拒绝 -window.addEventListener('unhandledrejection', function(e) { - console.error('未处理的Promise拒绝:', e.reason); - showToast('网络请求失败,请检查网络连接', 'error'); -}); - -// 导出函数供测试使用 -if (typeof module !== 'undefined' && module.exports) { - module.exports = { - handleProcess, - copyToClipboard, - showToast, - debounce, - throttle - }; -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/哈希解压压缩/接口集合.json b/frontend/60sapi/实用功能/哈希解压压缩/接口集合.json deleted file mode 100755 index 547b2771..00000000 --- a/frontend/60sapi/实用功能/哈希解压压缩/接口集合.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "https://60s.api.shumengya.top" -] diff --git a/frontend/60sapi/实用功能/哈希解压压缩/返回接口.json b/frontend/60sapi/实用功能/哈希解压压缩/返回接口.json deleted file mode 100755 index ed6fc83c..00000000 --- a/frontend/60sapi/实用功能/哈希解压压缩/返回接口.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "code": 200, - "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", - "data": { - "source": "hello", - "md5": "5d41402abc4b2a76b9719d911017c592", - "sha": { - "sha1": "aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d", - "sha256": "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824", - "sha512": "9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043" - }, - "base64": { - "encoded": "aGVsbG8=", - "decoded": "" - }, - "url": { - "encoded": "hello", - "decoded": "hello" - }, - "gzip": { - "encoded": "1f8b0800000000000003cb48cdc9c9070086a6103605000000", - "decoded": "" - }, - "deflate": { - "encoded": "789ccb48cdc9c90700062c0215", - "decoded": "" - }, - "brotli": { - "encoded": "0b028068656c6c6f03", - "decoded": "" - } - } -} - -注意:实际API返回的字段名是 encoded/decoded,不是 encode/decode \ No newline at end of file diff --git a/frontend/60sapi/实用功能/天气预报/css/background.css b/frontend/60sapi/实用功能/天气预报/css/background.css deleted file mode 100755 index a9872b38..00000000 --- a/frontend/60sapi/实用功能/天气预报/css/background.css +++ /dev/null @@ -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; - } -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/天气预报/css/style.css b/frontend/60sapi/实用功能/天气预报/css/style.css deleted file mode 100755 index f3d52bde..00000000 --- a/frontend/60sapi/实用功能/天气预报/css/style.css +++ /dev/null @@ -1,412 +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; -} - -/* 更新时间 */ -.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; - } - - .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; - } - - .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; - } - - .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; - } -} - -/* 预报区域样式 */ -.forecast-section { - margin-top: 30px; - padding: 20px; - background: rgba(255, 255, 255, 0.95); - border-radius: 20px; - backdrop-filter: blur(10px); - box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); -} - -.forecast-section h3 { - color: #2d5a3d; - font-size: 1.5rem; - margin-bottom: 20px; - text-align: center; -} - -.forecast-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); - gap: 15px; -} - -.forecast-item { - background: rgba(255, 255, 255, 0.8); - border-radius: 15px; - padding: 15px; - text-align: center; - border: 1px solid rgba(168, 213, 186, 0.3); - transition: all 0.3s ease; -} - -.forecast-item:hover { - transform: translateY(-5px); - box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15); -} - -.forecast-date { - font-weight: bold; - color: #2d5a3d; - margin-bottom: 10px; - font-size: 1.1rem; -} - -.forecast-weather { - margin-bottom: 10px; -} - -.weather-day { - color: #666; - font-size: 0.9rem; -} - -.weather-night { - color: #888; - font-size: 0.85rem; -} - -.forecast-temp { - margin-bottom: 10px; - display: flex; - justify-content: center; - gap: 10px; -} - -.temp-high { - color: #ff6b6b; - font-weight: bold; - font-size: 1.2rem; -} - -.temp-low { - color: #4ecdc4; - font-size: 1rem; -} - -.forecast-wind { - color: #666; - font-size: 0.85rem; - margin-bottom: 5px; -} - -.forecast-humidity { - color: #888; - font-size: 0.8rem; -} - -/* 预报区域响应式设计 */ -@media (max-width: 768px) { - .forecast-grid { - grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); - gap: 10px; - } - - .forecast-item { - padding: 12px; - } - - .forecast-date { - font-size: 1rem; - } - - .temp-high { - font-size: 1.1rem; - } -} - -@media (max-width: 480px) { - .forecast-section { - padding: 15px; - } - - .forecast-grid { - grid-template-columns: repeat(2, 1fr); - } -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/天气预报/index.html b/frontend/60sapi/实用功能/天气预报/index.html deleted file mode 100755 index fac47523..00000000 --- a/frontend/60sapi/实用功能/天气预报/index.html +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - 天气预报 - - - - -
-
-

天气预报

-
- -
- -
- - - - - - -
- - - - \ No newline at end of file diff --git a/frontend/60sapi/实用功能/天气预报/js/script.js b/frontend/60sapi/实用功能/天气预报/js/script.js deleted file mode 100755 index 6361f580..00000000 --- a/frontend/60sapi/实用功能/天气预报/js/script.js +++ /dev/null @@ -1,211 +0,0 @@ -// 天气查询应用 -class WeatherApp { - constructor() { - this.apiEndpoints = [ - "https://60s.api.shumengya.top/v2/weather/forecast" - ]; - 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}?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, forecast } = data; - - // 显示位置信息 - document.getElementById('locationName').textContent = location.formatted; - document.getElementById('locationDetail').textContent = - `${location.province} ${location.city} | 邮编: ${location.zip_code}`; - - // 使用第一天的预报数据作为当前天气(今天的天气) - const todayWeather = forecast[0]; - - // 显示当前天气(使用今天的最高温度) - document.getElementById('temperature').textContent = todayWeather.temperature_high; - document.getElementById('weatherCondition').textContent = - `${todayWeather.weather_day} 转 ${todayWeather.weather_night}`; - - // 体感温度(使用温度范围) - document.getElementById('feelsLike').textContent = - `温度范围 ${todayWeather.temperature_low}°C - ${todayWeather.temperature_high}°C`; - - // 显示更新时间(使用当前时间) - document.getElementById('updateTime').textContent = - `${this.formatDate(new Date())} (基于预报数据)`; - - // 显示天气预报 - this.displayForecast(forecast); - - this.showWeatherContainer(); - } - - displayForecast(forecast) { - const forecastGrid = document.getElementById('forecastGrid'); - forecastGrid.innerHTML = ''; - - forecast.forEach((day, index) => { - const forecastItem = document.createElement('div'); - forecastItem.className = 'forecast-item'; - - forecastItem.innerHTML = ` -
${day.date_desc}
-
-
${day.weather_day}
-
${day.weather_night}
-
-
- ${day.temperature_high}° - ${day.temperature_low}° -
-
-
${day.wind_direction_day} ${day.wind_strength_day}
-
-
湿度: ${day.humidity}%
- `; - - forecastGrid.appendChild(forecastItem); - }); - } - - // 华氏度转摄氏度 - fahrenheitToCelsius(fahrenheit) { - const celsius = (fahrenheit - 32) * 5 / 9; - return Math.round(celsius * 10) / 10; // 保留一位小数 - } - - // 格式化时间 - 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}`; - } - - 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; - } -} - -// 页面加载完成后初始化应用 -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(); -}); \ No newline at end of file diff --git a/frontend/60sapi/实用功能/天气预报/接口集合.json b/frontend/60sapi/实用功能/天气预报/接口集合.json deleted file mode 100755 index 178eeacc..00000000 --- a/frontend/60sapi/实用功能/天气预报/接口集合.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "https://60s.api.shumengya.top/v2/weather/forecast" -] diff --git a/frontend/60sapi/实用功能/天气预报/返回接口.json b/frontend/60sapi/实用功能/天气预报/返回接口.json deleted file mode 100755 index 7de58048..00000000 --- a/frontend/60sapi/实用功能/天气预报/返回接口.json +++ /dev/null @@ -1,101 +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" - }, - "forecast": [ - { - "date": "9/4", - "date_desc": "今天", - "weather_day": "多云", - "weather_night": "阴", - "weather_code_day": "01", - "weather_code_night": "02", - "temperature_high": 31, - "temperature_low": 21, - "wind_direction_day": "南风", - "wind_direction_night": "南风", - "wind_strength_day": "\u003C3级", - "wind_strength_night": "\u003C3级", - "rainfall": 96.1, - "humidity": 83 - }, - { - "date": "9/5", - "date_desc": "星期五", - "weather_day": "中雨", - "weather_night": "多云", - "weather_code_day": "08", - "weather_code_night": "01", - "temperature_high": 23, - "temperature_low": 19, - "wind_direction_day": "西南风", - "wind_direction_night": "北风", - "wind_strength_day": "\u003C3级", - "wind_strength_night": "\u003C3级", - "rainfall": 100, - "humidity": 68 - }, - { - "date": "9/6", - "date_desc": "星期六", - "weather_day": "多云", - "weather_night": "晴", - "weather_code_day": "01", - "weather_code_night": "00", - "temperature_high": 30, - "temperature_low": 19, - "wind_direction_day": "南风", - "wind_direction_night": "西南风", - "wind_strength_day": "\u003C3级", - "wind_strength_night": "\u003C3级", - "rainfall": 85.2, - "humidity": 36 - }, - { - "date": "9/7", - "date_desc": "星期日", - "weather_day": "多云", - "weather_night": "晴", - "weather_code_day": "01", - "weather_code_night": "00", - "temperature_high": 29, - "temperature_low": 20, - "wind_direction_day": "北风", - "wind_direction_night": "北风", - "wind_strength_day": "\u003C3级", - "wind_strength_night": "\u003C3级", - "rainfall": 87.3, - "humidity": 27 - }, - { - "date": "9/8", - "date_desc": "星期一", - "weather_day": "多云", - "weather_night": "多云", - "weather_code_day": "01", - "weather_code_night": "01", - "temperature_high": 28, - "temperature_low": 20, - "wind_direction_day": "南风", - "wind_direction_night": "南风", - "wind_strength_day": "\u003C3级", - "wind_strength_night": "\u003C3级", - "rainfall": 84.8, - "humidity": 41 - } - ] - } -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/实时天气[目前有问题]/background.css b/frontend/60sapi/实用功能/实时天气[目前有问题]/background.css deleted file mode 100644 index 078de8fa..00000000 --- a/frontend/60sapi/实用功能/实时天气[目前有问题]/background.css +++ /dev/null @@ -1,202 +0,0 @@ -/* 背景样式文件 - 独立管理背景相关CSS */ - -/* 主体背景 */ -body { - background: linear-gradient(135deg, #a8e6cf 0%, #dcedc8 50%, #f0f4c3 100%); - background-attachment: fixed; - background-size: cover; - 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, 219, 226, 0.1) 0%, transparent 50%), - radial-gradient(circle at 80% 20%, rgba(168, 230, 207, 0.1) 0%, transparent 50%), - radial-gradient(circle at 40% 40%, rgba(220, 237, 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: - linear-gradient(45deg, transparent 30%, rgba(255, 255, 255, 0.05) 50%, transparent 70%), - linear-gradient(-45deg, transparent 30%, rgba(168, 230, 207, 0.05) 50%, transparent 70%); - background-size: 200px 200px; - animation: backgroundMove 20s linear infinite; - pointer-events: none; - z-index: -1; -} - -/* 背景动画 */ -@keyframes backgroundMove { - 0% { - background-position: 0 0, 0 0; - } - 100% { - background-position: 200px 200px, -200px -200px; - } -} - -/* 容器背景 */ -.container { - background: rgba(255, 255, 255, 0.1); - backdrop-filter: blur(5px); - border-radius: 20px; - border: 1px solid rgba(255, 255, 255, 0.2); -} - -/* 卡片背景增强 */ -.weather-card { - background: rgba(255, 255, 255, 0.95); - backdrop-filter: blur(15px); - border: 1px solid rgba(168, 230, 207, 0.3); - box-shadow: - 0 10px 30px rgba(0, 0, 0, 0.1), - 0 1px 8px rgba(168, 230, 207, 0.2), - inset 0 1px 0 rgba(255, 255, 255, 0.8); -} - -/* 当前天气区域背景 */ -.current-weather { - background: linear-gradient(135deg, - rgba(168, 230, 207, 0.8) 0%, - rgba(220, 237, 200, 0.8) 50%, - rgba(240, 244, 195, 0.8) 100%); - backdrop-filter: blur(10px); - border: 1px solid rgba(255, 255, 255, 0.3); - box-shadow: - 0 4px 15px rgba(39, 174, 96, 0.1), - inset 0 1px 0 rgba(255, 255, 255, 0.6); -} - -/* 详情项背景 */ -.detail-item { - background: linear-gradient(135deg, - rgba(168, 230, 207, 0.1) 0%, - rgba(255, 255, 255, 0.1) 100%); - backdrop-filter: blur(5px); - border: 1px solid rgba(168, 230, 207, 0.2); - box-shadow: 0 2px 8px rgba(39, 174, 96, 0.05); -} - -/* 生活指数项背景 */ -.index-item { - background: linear-gradient(135deg, - rgba(168, 230, 207, 0.05) 0%, - rgba(255, 255, 255, 0.1) 100%); - backdrop-filter: blur(5px); - border: 1px solid rgba(168, 230, 207, 0.15); - box-shadow: 0 2px 10px rgba(39, 174, 96, 0.05); -} - -.index-item:hover { - background: linear-gradient(135deg, - rgba(168, 230, 207, 0.1) 0%, - rgba(255, 255, 255, 0.15) 100%); - box-shadow: 0 5px 20px rgba(39, 174, 96, 0.1); -} - -/* 输入框背景 */ -#cityInput { - background: rgba(255, 255, 255, 0.9); - backdrop-filter: blur(10px); - border: 2px solid rgba(168, 230, 207, 0.6); - box-shadow: 0 2px 10px rgba(39, 174, 96, 0.1); -} - -#cityInput:focus { - background: rgba(255, 255, 255, 0.95); - box-shadow: - 0 0 15px rgba(39, 174, 96, 0.2), - 0 2px 10px rgba(39, 174, 96, 0.1); -} - -/* 按钮背景 */ -#searchBtn { - background: linear-gradient(135deg, - #27ae60 0%, - #2ecc71 50%, - #58d68d 100%); - box-shadow: - 0 4px 15px rgba(39, 174, 96, 0.3), - inset 0 1px 0 rgba(255, 255, 255, 0.2); -} - -#searchBtn:hover { - background: linear-gradient(135deg, - #229954 0%, - #27ae60 50%, - #52c370 100%); - box-shadow: - 0 6px 20px rgba(39, 174, 96, 0.4), - inset 0 1px 0 rgba(255, 255, 255, 0.3); -} - -/* 错误消息背景 */ -.error-message { - background: linear-gradient(135deg, - rgba(231, 76, 60, 0.1) 0%, - rgba(255, 255, 255, 0.1) 100%); - backdrop-filter: blur(10px); - border: 1px solid rgba(231, 76, 60, 0.2); - box-shadow: 0 4px 15px rgba(231, 76, 60, 0.1); -} - -/* 加载状态背景 */ -.loading { - background: rgba(255, 255, 255, 0.8); - backdrop-filter: blur(10px); - border-radius: 15px; - border: 1px solid rgba(168, 230, 207, 0.3); - box-shadow: 0 4px 15px rgba(39, 174, 96, 0.1); -} - -/* 移动端背景优化 */ -@media (max-width: 767px) { - body::after { - background-size: 100px 100px; - animation-duration: 15s; - } - - .container { - background: rgba(255, 255, 255, 0.05); - backdrop-filter: blur(3px); - } - - .weather-card { - backdrop-filter: blur(10px); - } -} - -/* 高性能设备背景增强 */ -@media (min-width: 1024px) { - body::before { - background-image: - radial-gradient(circle at 20% 80%, rgba(120, 219, 226, 0.15) 0%, transparent 50%), - radial-gradient(circle at 80% 20%, rgba(168, 230, 207, 0.15) 0%, transparent 50%), - radial-gradient(circle at 40% 40%, rgba(220, 237, 200, 0.15) 0%, transparent 50%), - radial-gradient(circle at 60% 70%, rgba(240, 244, 195, 0.1) 0%, transparent 50%); - } - - .weather-card { - backdrop-filter: blur(20px); - } - - .current-weather { - backdrop-filter: blur(15px); - } -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/实时天气[目前有问题]/index.html b/frontend/60sapi/实用功能/实时天气[目前有问题]/index.html deleted file mode 100644 index 5a632718..00000000 --- a/frontend/60sapi/实用功能/实时天气[目前有问题]/index.html +++ /dev/null @@ -1,143 +0,0 @@ - - - - - - 实时天气查询 - - - - -
-
-

实时天气

- -
- -
-
正在加载天气数据...
- - - - -
-
- - - - \ No newline at end of file diff --git a/frontend/60sapi/实用功能/实时天气[目前有问题]/script.js b/frontend/60sapi/实用功能/实时天气[目前有问题]/script.js deleted file mode 100644 index bb339d26..00000000 --- a/frontend/60sapi/实用功能/实时天气[目前有问题]/script.js +++ /dev/null @@ -1,354 +0,0 @@ -// 天气应用主要功能 -class WeatherApp { - constructor() { - this.apiUrl = 'https://60s.api.shumengya.top/v2/weather'; - this.init(); - } - - init() { - this.bindEvents(); - this.loadWeather('北京'); // 默认加载北京天气 - } - - bindEvents() { - const searchBtn = document.getElementById('searchBtn'); - const cityInput = document.getElementById('cityInput'); - - // 搜索按钮点击事件 - searchBtn.addEventListener('click', () => { - const city = cityInput.value.trim(); - if (city) { - this.loadWeather(city); - } - }); - - // 输入框回车事件 - cityInput.addEventListener('keypress', (e) => { - if (e.key === 'Enter') { - const city = cityInput.value.trim(); - if (city) { - this.loadWeather(city); - } - } - }); - } - - async loadWeather(city) { - this.showLoading(); - - try { - const response = await fetch(`${this.apiUrl}?query=${encodeURIComponent(city)}`); - - if (!response.ok) { - throw new Error(`HTTP错误: ${response.status}`); - } - - const data = await response.json(); - console.log('完整API响应:', data); // 调试日志 - - if (data.code === 200 && data.data) { - this.displayWeather(data.data); - this.hideLoading(); - } else { - throw new Error(data.message || `API返回错误: code=${data.code}`); - } - } catch (error) { - console.error('获取天气数据失败:', error); - console.error('错误详情:', { - message: error.message, - stack: error.stack - }); - this.showError(error.message); - this.hideLoading(); - } - } - - showLoading() { - document.getElementById('loading').style.display = 'block'; - document.getElementById('weatherCard').style.display = 'none'; - document.getElementById('errorMessage').style.display = 'none'; - } - - hideLoading() { - document.getElementById('loading').style.display = 'none'; - } - - showError(message = '获取天气数据失败,请检查网络连接或稍后重试') { - const errorElement = document.getElementById('errorMessage'); - const errorText = errorElement.querySelector('p'); - - if (errorText) { - errorText.textContent = message; - } - - errorElement.style.display = 'block'; - document.getElementById('weatherCard').style.display = 'none'; - } - - displayWeather(data) { - console.log('API返回数据:', data); // 调试日志 - - // 根据实际API结构解构数据 - const location = data.location || {}; - const realtime = data.realtime || {}; - const air_quality = realtime.air_quality || {}; - const life_indices = realtime.life_indices || []; - - // 显示位置信息 - const locationName = location.formatted || location.city || location.name || '未知位置'; - document.getElementById('locationName').textContent = locationName; - - const updateTime = realtime.updated || '未知时间'; - document.getElementById('updateTime').textContent = `更新时间: ${updateTime}`; - - // 显示当前天气 - const temperature = realtime.temperature !== undefined ? realtime.temperature : '--'; - document.getElementById('temperature').textContent = `${temperature}°C`; - - const condition = realtime.weather || realtime.weather_desc || '未知'; - document.getElementById('weatherDesc').textContent = condition; - document.getElementById('weatherIcon').textContent = this.getWeatherIcon(condition); - - // 显示天气详情 - const feelsLike = realtime.temperature_feels_like !== undefined ? realtime.temperature_feels_like : temperature; - document.getElementById('feelsLike').textContent = `${feelsLike}°C`; - - const humidity = realtime.humidity !== undefined ? realtime.humidity : '--'; - document.getElementById('humidity').textContent = `${humidity}%`; - - const windDirection = realtime.wind_direction || '--'; - document.getElementById('windDirection').textContent = windDirection; - - const windPower = realtime.wind_power || realtime.wind_strength || '--'; - document.getElementById('windStrength').textContent = windPower; - - const pressure = realtime.pressure !== undefined ? realtime.pressure : '--'; - document.getElementById('pressure').textContent = `${pressure} hPa`; - - document.getElementById('visibility').textContent = '--'; // API中没有能见度数据 - - const aqi = air_quality.aqi !== undefined ? air_quality.aqi : '--'; - document.getElementById('aqi').textContent = `AQI ${aqi}`; - - const pm25 = air_quality.pm25 !== undefined ? air_quality.pm25 : '--'; - document.getElementById('pm25').textContent = `${pm25} μg/m³`; - - // 显示生活指数 - if (life_indices && life_indices.length > 0) { - this.displayLifeIndex(life_indices); - } else { - // 如果没有生活指数数据,重置显示 - this.resetLifeIndex(); - } - - // 显示天气卡片 - document.getElementById('weatherCard').style.display = 'block'; - } - - displayLifeIndex(lifeIndices) { - const indexMap = { - comfort: { level: 'comfortLevel', desc: 'comfortDesc' }, - clothes: { level: 'clothingLevel', desc: 'clothingDesc' }, - umbrella: { level: 'umbrellaLevel', desc: 'umbrellaDesc' }, - ultraviolet: { level: 'uvLevel', desc: 'uvDesc' }, - carwash: { level: 'carWashLevel', desc: 'carWashDesc' }, - tourism: { level: 'travelLevel', desc: 'travelDesc' }, - sports: { level: 'sportLevel', desc: 'sportDesc' } - }; - - // 重置所有指数显示 - this.resetLifeIndex(); - - // 根据新的API数据结构更新生活指数 - if (Array.isArray(lifeIndices)) { - lifeIndices.forEach(index => { - if (index && index.key && indexMap[index.key]) { - const { level, desc } = indexMap[index.key]; - const levelElement = document.getElementById(level); - const descElement = document.getElementById(desc); - - if (levelElement) levelElement.textContent = index.level || '--'; - if (descElement) descElement.textContent = index.description || '--'; - } - }); - } - } - - resetLifeIndex() { - const indexMap = { - comfort: { level: 'comfortLevel', desc: 'comfortDesc' }, - clothes: { level: 'clothingLevel', desc: 'clothingDesc' }, - umbrella: { level: 'umbrellaLevel', desc: 'umbrellaDesc' }, - ultraviolet: { level: 'uvLevel', desc: 'uvDesc' }, - carwash: { level: 'carWashLevel', desc: 'carWashDesc' }, - tourism: { level: 'travelLevel', desc: 'travelDesc' }, - sports: { level: 'sportLevel', desc: 'sportDesc' } - }; - - Object.values(indexMap).forEach(({ level, desc }) => { - const levelElement = document.getElementById(level); - const descElement = document.getElementById(desc); - - if (levelElement) levelElement.textContent = '--'; - if (descElement) descElement.textContent = '--'; - }); - } - - getWeatherIcon(weather) { - const iconMap = { - '晴': '☀️', - '多云': '⛅', - '阴': '☁️', - '小雨': '🌦️', - '中雨': '🌧️', - '大雨': '⛈️', - '雷阵雨': '⛈️', - '雪': '❄️', - '小雪': '🌨️', - '中雪': '❄️', - '大雪': '❄️', - '雾': '🌫️', - '霾': '😷', - '沙尘暴': '🌪️' - }; - - // 查找匹配的天气图标 - for (const [key, icon] of Object.entries(iconMap)) { - if (weather.includes(key)) { - return icon; - } - } - - // 默认图标 - return '🌤️'; - } - - // 获取空气质量等级颜色 - getAQIColor(aqi) { - if (aqi <= 50) return '#00e400'; - if (aqi <= 100) return '#ffff00'; - if (aqi <= 150) return '#ff7e00'; - if (aqi <= 200) return '#ff0000'; - if (aqi <= 300) return '#8f3f97'; - return '#7e0023'; - } - - // 格式化时间 - formatTime(timeString) { - try { - const date = new Date(timeString); - return date.toLocaleString('zh-CN', { - year: 'numeric', - month: '2-digit', - day: '2-digit', - hour: '2-digit', - minute: '2-digit' - }); - } catch (error) { - return timeString; - } - } -} - -// 页面加载完成后初始化应用 -document.addEventListener('DOMContentLoaded', () => { - new WeatherApp(); -}); - -// 添加一些实用的工具函数 -const utils = { - // 防抖函数 - debounce(func, wait) { - let timeout; - return function executedFunction(...args) { - const later = () => { - clearTimeout(timeout); - func(...args); - }; - clearTimeout(timeout); - timeout = setTimeout(later, wait); - }; - }, - - // 节流函数 - 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); - } - }; - }, - - // 检查网络状态 - checkNetworkStatus() { - return navigator.onLine; - }, - - // 显示提示消息 - showToast(message, type = 'info') { - const toast = document.createElement('div'); - toast.className = `toast toast-${type}`; - toast.textContent = message; - toast.style.cssText = ` - position: fixed; - top: 20px; - right: 20px; - padding: 12px 20px; - background: ${type === 'error' ? '#e74c3c' : '#27ae60'}; - color: white; - border-radius: 8px; - z-index: 1000; - animation: slideIn 0.3s ease; - `; - - document.body.appendChild(toast); - - setTimeout(() => { - toast.style.animation = 'slideOut 0.3s ease'; - setTimeout(() => { - document.body.removeChild(toast); - }, 300); - }, 3000); - } -}; - -// 添加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); - -// 网络状态监听 -window.addEventListener('online', () => { - utils.showToast('网络连接已恢复', 'success'); -}); - -window.addEventListener('offline', () => { - utils.showToast('网络连接已断开', 'error'); -}); \ No newline at end of file diff --git a/frontend/60sapi/实用功能/实时天气[目前有问题]/styles.css b/frontend/60sapi/实用功能/实时天气[目前有问题]/styles.css deleted file mode 100644 index 88113f63..00000000 --- a/frontend/60sapi/实用功能/实时天气[目前有问题]/styles.css +++ /dev/null @@ -1,442 +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; -} - -.container { - max-width: 1200px; - margin: 0 auto; - padding: 20px; - min-height: 100vh; -} - -/* 头部样式 */ -.header { - text-align: center; - margin-bottom: 30px; -} - -.header h1 { - font-size: 2.5rem; - color: #27ae60; - margin-bottom: 20px; - font-weight: 300; - text-shadow: 0 2px 4px rgba(39, 174, 96, 0.1); -} - -.search-box { - display: flex; - justify-content: center; - gap: 10px; - margin-bottom: 20px; -} - -#cityInput { - padding: 12px 16px; - border: 2px solid #a8e6cf; - border-radius: 25px; - font-size: 16px; - outline: none; - background: rgba(255, 255, 255, 0.9); - transition: all 0.3s ease; - min-width: 200px; -} - -#cityInput:focus { - border-color: #27ae60; - box-shadow: 0 0 10px rgba(39, 174, 96, 0.2); -} - -#searchBtn { - padding: 12px 24px; - background: linear-gradient(135deg, #27ae60, #2ecc71); - color: white; - border: none; - border-radius: 25px; - font-size: 16px; - cursor: pointer; - transition: all 0.3s ease; - box-shadow: 0 4px 15px rgba(39, 174, 96, 0.3); -} - -#searchBtn:hover { - transform: translateY(-2px); - box-shadow: 0 6px 20px rgba(39, 174, 96, 0.4); -} - -#searchBtn:active { - transform: translateY(0); -} - -/* 主要内容区域 */ -.main-content { - display: flex; - justify-content: center; - align-items: flex-start; -} - -.loading { - text-align: center; - font-size: 18px; - color: #27ae60; - padding: 40px; -} - -.weather-card { - background: rgba(255, 255, 255, 0.95); - border-radius: 20px; - padding: 30px; - box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); - backdrop-filter: blur(10px); - border: 1px solid rgba(168, 230, 207, 0.3); - width: 100%; - max-width: 800px; -} - -/* 位置信息 */ -.location-info { - text-align: center; - margin-bottom: 30px; - padding-bottom: 20px; - border-bottom: 2px solid #a8e6cf; -} - -.location-info h2 { - font-size: 2rem; - color: #27ae60; - margin-bottom: 10px; -} - -.location-info p { - color: #7f8c8d; - font-size: 14px; -} - -/* 当前天气 */ -.current-weather { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 30px; - padding: 20px; - background: linear-gradient(135deg, #a8e6cf, #dcedc8); - border-radius: 15px; -} - -.temperature-section { - display: flex; - flex-direction: column; - align-items: flex-start; -} - -.temperature { - font-size: 3.5rem; - font-weight: 300; - color: #27ae60; - line-height: 1; -} - -.weather-desc { - font-size: 1.2rem; - color: #2c3e50; - margin-top: 5px; -} - -.weather-icon { - font-size: 4rem; - opacity: 0.8; -} - -/* 天气详情 */ -.weather-details { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); - gap: 15px; - margin-bottom: 30px; -} - -.detail-item { - display: flex; - justify-content: space-between; - align-items: center; - padding: 15px; - background: rgba(168, 230, 207, 0.1); - border-radius: 10px; - border-left: 4px solid #27ae60; -} - -.detail-item .label { - color: #7f8c8d; - font-size: 14px; -} - -.detail-item .value { - color: #2c3e50; - font-weight: 500; - font-size: 16px; -} - -/* 生活指数 */ -.life-index h3 { - color: #27ae60; - margin-bottom: 20px; - font-size: 1.5rem; - text-align: center; -} - -.index-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); - gap: 20px; -} - -.index-item { - display: flex; - align-items: flex-start; - padding: 20px; - background: rgba(168, 230, 207, 0.05); - border-radius: 15px; - border: 1px solid rgba(168, 230, 207, 0.2); - transition: all 0.3s ease; -} - -.index-item:hover { - transform: translateY(-2px); - box-shadow: 0 5px 15px rgba(39, 174, 96, 0.1); -} - -.index-icon { - font-size: 2rem; - margin-right: 15px; - opacity: 0.8; -} - -.index-content { - flex: 1; -} - -.index-title { - font-weight: 500; - color: #2c3e50; - margin-bottom: 5px; -} - -.index-level { - color: #27ae60; - font-weight: 600; - margin-bottom: 5px; -} - -.index-desc { - color: #7f8c8d; - font-size: 14px; - line-height: 1.4; -} - -.error-message { - text-align: center; - padding: 40px; - color: #e74c3c; - background: rgba(231, 76, 60, 0.1); - border-radius: 15px; - border: 1px solid rgba(231, 76, 60, 0.2); -} - -/* 平板端适配 (768px - 1024px) */ -@media (min-width: 768px) and (max-width: 1024px) { - .container { - padding: 25px; - } - - .header h1 { - font-size: 2.8rem; - } - - .search-box { - max-width: 500px; - margin: 0 auto 20px; - } - - .weather-details { - grid-template-columns: repeat(2, 1fr); - } - - .index-grid { - grid-template-columns: repeat(2, 1fr); - } - - .current-weather { - padding: 25px; - } - - .temperature { - font-size: 4rem; - } -} - -/* 电脑端适配 (1024px+) */ -@media (min-width: 1024px) { - .container { - padding: 40px; - } - - .header h1 { - font-size: 3.2rem; - } - - .search-box { - max-width: 600px; - margin: 0 auto 30px; - } - - .weather-card { - padding: 40px; - } - - .weather-details { - grid-template-columns: repeat(4, 1fr); - } - - .index-grid { - grid-template-columns: repeat(3, 1fr); - } - - .current-weather { - padding: 30px; - } - - .temperature { - font-size: 4.5rem; - } - - .index-item { - padding: 25px; - } -} - -/* 手机端适配 (优先优化) */ -@media (max-width: 767px) { - .container { - padding: 15px; - } - - .header h1 { - font-size: 2rem; - margin-bottom: 15px; - } - - .search-box { - flex-direction: column; - align-items: center; - gap: 15px; - } - - #cityInput { - width: 100%; - max-width: 300px; - font-size: 16px; - } - - #searchBtn { - width: 100%; - max-width: 300px; - padding: 14px 24px; - } - - .weather-card { - padding: 20px; - margin: 0; - } - - .current-weather { - flex-direction: column; - text-align: center; - gap: 20px; - padding: 20px; - } - - .temperature { - font-size: 3rem; - } - - .weather-icon { - font-size: 3rem; - } - - .weather-details { - grid-template-columns: 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; - margin-right: 10px; - } - - .life-index h3 { - font-size: 1.3rem; - margin-bottom: 15px; - } - - .location-info h2 { - font-size: 1.5rem; - } -} - -/* 超小屏幕适配 */ -@media (max-width: 480px) { - .container { - padding: 10px; - } - - .header h1 { - font-size: 1.8rem; - } - - .weather-card { - padding: 15px; - } - - .temperature { - font-size: 2.5rem; - } - - .current-weather { - padding: 15px; - } - - .detail-item { - padding: 10px; - font-size: 14px; - } - - .index-item { - padding: 12px; - } - - .index-desc { - font-size: 13px; - } -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/实时天气[目前有问题]/返回接口.json b/frontend/60sapi/实用功能/实时天气[目前有问题]/返回接口.json deleted file mode 100644 index 671a75a4..00000000 --- a/frontend/60sapi/实用功能/实时天气[目前有问题]/返回接口.json +++ /dev/null @@ -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": "d0", - "temperature": 999, - "temperature_feels_like": 75.6, - "humidity": 63, - "wind_direction": "南风", - "wind_strength": "3-4级转\u003C3级", - "wind_speed": "1km/h", - "pressure": 1006, - "visibility": "21km", - "aqi": 41, - "pm25": 41, - "rainfall": 0, - "rainfall_24h": 0, - "updated": "2025-09-08 08:00:00", - "updated_at": "20:30", - "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": "有降水,推荐您在室内进行休闲运动。" - } - } - } - } -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/密码强度检测/css/style.css b/frontend/60sapi/实用功能/密码强度检测/css/style.css deleted file mode 100644 index 858e4bea..00000000 --- a/frontend/60sapi/实用功能/密码强度检测/css/style.css +++ /dev/null @@ -1,878 +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: #2c3e50; - 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: 40px 20px; - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - border-radius: 20px; - box-shadow: 0 10px 30px rgba(102, 126, 234, 0.3); - color: white; -} - -.header h1 { - font-size: 2.8rem; - font-weight: 700; - margin-bottom: 15px; - text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); -} - -.subtitle { - font-size: 1.2rem; - opacity: 0.9; - font-weight: 400; -} - -/* 主内容区域 */ -.main-content { - flex: 1; - display: flex; - flex-direction: column; - gap: 30px; -} - -/* 输入容器 */ -.input-container { - background: #ffffff; - border-radius: 20px; - padding: 40px; - box-shadow: 0 10px 40px rgba(0, 0, 0, 0.1); - border: 1px solid #e8ecf4; -} - -.input-group { - margin-bottom: 30px; -} - -.input-label { - display: block; - font-size: 1.1rem; - font-weight: 600; - color: #2c3e50; - margin-bottom: 15px; -} - -.password-input-wrapper { - position: relative; - margin-bottom: 15px; -} - -.password-input { - width: 100%; - padding: 18px 60px 18px 20px; - border: 2px solid #e8ecf4; - border-radius: 12px; - font-size: 1.1rem; - font-family: 'Courier New', monospace; - background: #f8fafc; - transition: all 0.3s ease; - letter-spacing: 1px; -} - -.password-input:focus { - outline: none; - border-color: #667eea; - background: #ffffff; - box-shadow: 0 0 0 4px rgba(102, 126, 234, 0.1); -} - -.password-input::placeholder { - color: #94a3b8; - letter-spacing: normal; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; -} - -.toggle-visibility { - position: absolute; - right: 15px; - top: 50%; - transform: translateY(-50%); - background: none; - border: none; - cursor: pointer; - padding: 8px; - border-radius: 6px; - color: #64748b; - transition: all 0.3s ease; -} - -.toggle-visibility:hover { - background: #f1f5f9; - color: #475569; -} - -.input-hint { - display: flex; - align-items: center; - gap: 8px; - color: #64748b; - font-size: 0.9rem; -} - -.hint-icon { - font-size: 1rem; -} - -/* 检测按钮 */ -.check-btn { - width: 100%; - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - color: white; - border: none; - padding: 18px 32px; - border-radius: 12px; - font-size: 1.1rem; - font-weight: 600; - cursor: pointer; - transition: all 0.3s ease; - box-shadow: 0 4px 20px rgba(102, 126, 234, 0.3); - display: flex; - align-items: center; - justify-content: center; - gap: 10px; - position: relative; - overflow: hidden; -} - -.check-btn:hover { - transform: translateY(-2px); - box-shadow: 0 6px 25px rgba(102, 126, 234, 0.4); -} - -.check-btn:active { - transform: translateY(0); -} - -.check-btn:disabled { - opacity: 0.7; - cursor: not-allowed; - transform: none; -} - -.btn-icon { - font-size: 1.2rem; -} - -/* 结果容器 */ -.result-container { - background: #ffffff; - border-radius: 20px; - padding: 40px; - box-shadow: 0 10px 40px rgba(0, 0, 0, 0.1); - border: 1px solid #e8ecf4; - animation: slideIn 0.5s ease-out; -} - -@keyframes slideIn { - from { - opacity: 0; - transform: translateY(30px); - } - to { - opacity: 1; - transform: translateY(0); - } -} - -/* 强度概览 */ -.strength-overview { - margin-bottom: 40px; - padding: 30px; - background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%); - border-radius: 16px; - border: 1px solid #e2e8f0; -} - -.strength-score { - display: flex; - align-items: center; - gap: 30px; - margin-bottom: 25px; -} - -.score-circle { - width: 120px; - height: 120px; - border-radius: 50%; - background: conic-gradient(from 0deg, #e2e8f0 0deg, #e2e8f0 360deg); - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - position: relative; - transition: all 0.5s ease; -} - -.score-circle::before { - content: ''; - position: absolute; - width: 90px; - height: 90px; - background: white; - border-radius: 50%; - z-index: 1; -} - -.score-value { - font-size: 2.5rem; - font-weight: 700; - color: #2c3e50; - z-index: 2; - position: relative; -} - -.score-label { - font-size: 0.9rem; - color: #64748b; - z-index: 2; - position: relative; -} - -.strength-info { - flex: 1; -} - -.strength-level { - font-size: 2rem; - font-weight: 700; - margin-bottom: 8px; - color: #2c3e50; -} - -.strength-description { - font-size: 1.1rem; - color: #64748b; - line-height: 1.5; -} - -.strength-bar { - margin-top: 20px; -} - -.bar-background { - width: 100%; - height: 12px; - background: #e2e8f0; - border-radius: 6px; - overflow: hidden; - margin-bottom: 10px; -} - -.bar-fill { - height: 100%; - background: linear-gradient(90deg, #ef4444, #f97316, #eab308, #22c55e); - border-radius: 6px; - width: 0%; - transition: width 0.8s ease; -} - -.bar-labels { - display: flex; - justify-content: space-between; - font-size: 0.85rem; - color: #64748b; -} - -/* 详细信息网格 */ -.details-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); - gap: 25px; - margin-bottom: 30px; -} - -.detail-card { - background: #f8fafc; - border-radius: 16px; - padding: 25px; - border: 1px solid #e2e8f0; - transition: all 0.3s ease; -} - -.detail-card:hover { - transform: translateY(-2px); - box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1); -} - -.card-header { - display: flex; - align-items: center; - gap: 12px; - margin-bottom: 20px; -} - -.card-icon { - font-size: 1.5rem; -} - -.card-header h3 { - font-size: 1.3rem; - font-weight: 600; - color: #2c3e50; -} - -.card-content { - display: flex; - flex-direction: column; - gap: 15px; -} - -.info-row { - display: flex; - justify-content: space-between; - align-items: center; - padding: 12px 0; - border-bottom: 1px solid #e2e8f0; -} - -.info-row:last-child { - border-bottom: none; -} - -.info-label { - font-weight: 500; - color: #64748b; -} - -.info-value { - font-weight: 600; - color: #2c3e50; -} - -/* 字符类型分析 */ -.character-types { - display: grid; - grid-template-columns: repeat(2, 1fr); - gap: 12px; - margin-bottom: 20px; -} - -.char-type { - display: flex; - align-items: center; - gap: 8px; - padding: 10px 12px; - background: white; - border-radius: 8px; - border: 1px solid #e2e8f0; - font-size: 0.9rem; -} - -.char-type.has-type { - background: #dcfce7; - border-color: #bbf7d0; - color: #166534; -} - -.char-type.has-type .type-icon { - color: #22c55e; -} - -.type-icon { - font-size: 1rem; -} - -.character-issues { - display: flex; - flex-direction: column; - gap: 8px; -} - -.issue-item { - display: flex; - align-items: center; - gap: 8px; - padding: 8px 12px; - background: #fef2f2; - border: 1px solid #fecaca; - border-radius: 8px; - color: #dc2626; - font-size: 0.9rem; -} - -.issue-item.hidden { - display: none; -} - -.issue-icon { - font-size: 1rem; -} - -/* 建议和提示区域 */ -.recommendations-section { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(350px, 1fr)); - gap: 25px; -} - -.recommendations-card, -.security-tips-card { - background: #f8fafc; - border-radius: 16px; - padding: 25px; - border: 1px solid #e2e8f0; -} - -.recommendations-list { - list-style: none; - display: flex; - flex-direction: column; - gap: 12px; -} - -.recommendations-list li { - display: flex; - align-items: flex-start; - gap: 10px; - padding: 12px 16px; - background: white; - border-radius: 10px; - border: 1px solid #e2e8f0; - color: #2c3e50; - line-height: 1.5; -} - -.recommendations-list li::before { - content: '💡'; - font-size: 1rem; - margin-top: 2px; - flex-shrink: 0; -} - -.tips-container { - display: flex; - flex-direction: column; - gap: 12px; -} - -.tip-item { - display: flex; - align-items: flex-start; - gap: 12px; - padding: 12px 16px; - background: white; - border-radius: 10px; - border: 1px solid #e2e8f0; - color: #2c3e50; - line-height: 1.5; -} - -.tip-icon { - font-size: 1rem; - margin-top: 2px; - flex-shrink: 0; -} - -/* 错误容器 */ -.error-container { - background: #ffffff; - border-radius: 20px; - padding: 50px 40px; - text-align: center; - box-shadow: 0 10px 40px rgba(239, 68, 68, 0.1); - border: 1px solid #fecaca; -} - -.error-icon { - font-size: 4rem; - margin-bottom: 20px; -} - -.error-container h3 { - color: #dc2626; - margin-bottom: 15px; - font-size: 1.5rem; - font-weight: 600; -} - -.error-container p { - color: #64748b; - margin-bottom: 25px; - font-size: 1.1rem; -} - -.retry-btn { - background: #dc2626; - color: white; - border: none; - padding: 14px 28px; - border-radius: 10px; - font-weight: 600; - cursor: pointer; - transition: all 0.3s ease; - font-size: 1rem; -} - -.retry-btn:hover { - background: #b91c1c; - transform: translateY(-1px); -} - -/* 页脚 */ -.footer { - text-align: center; - padding: 40px 20px; - color: #64748b; - margin-top: 40px; -} - -.footer p { - margin-bottom: 8px; - font-size: 1rem; -} - -.footer-note { - font-size: 0.9rem; - opacity: 0.8; -} - -/* 提示框 */ -.toast { - position: fixed; - top: 20px; - right: 20px; - background: #22c55e; - color: white; - padding: 16px 24px; - border-radius: 10px; - box-shadow: 0 4px 20px rgba(34, 197, 94, 0.3); - z-index: 1000; - animation: toastSlide 0.3s ease-out; - font-weight: 500; -} - -@keyframes toastSlide { - from { - transform: translateX(100%); - opacity: 0; - } - to { - transform: translateX(0); - opacity: 1; - } -} - -/* 强度等级颜色 */ -.strength-weak { - color: #dc2626 !important; -} - -.strength-medium { - color: #f59e0b !important; -} - -.strength-strong { - color: #059669 !important; -} - -.strength-very-strong { - color: #047857 !important; -} - -/* 分数圆圈颜色 */ -.score-weak { - background: conic-gradient(from 0deg, #dc2626 0deg, #dc2626 var(--score-deg), #e2e8f0 var(--score-deg), #e2e8f0 360deg) !important; -} - -.score-medium { - background: conic-gradient(from 0deg, #f59e0b 0deg, #f59e0b var(--score-deg), #e2e8f0 var(--score-deg), #e2e8f0 360deg) !important; -} - -.score-strong { - background: conic-gradient(from 0deg, #059669 0deg, #059669 var(--score-deg), #e2e8f0 var(--score-deg), #e2e8f0 360deg) !important; -} - -.score-very-strong { - background: conic-gradient(from 0deg, #047857 0deg, #047857 var(--score-deg), #e2e8f0 var(--score-deg), #e2e8f0 360deg) !important; -} - -/* 平板端适配 (768px - 1024px) */ -@media (min-width: 768px) and (max-width: 1024px) { - .container { - max-width: 900px; - padding: 25px; - } - - .header h1 { - font-size: 2.4rem; - } - - .input-container, - .result-container { - padding: 30px; - } - - .details-grid { - grid-template-columns: 1fr; - } - - .recommendations-section { - grid-template-columns: 1fr; - } - - .strength-score { - flex-direction: column; - text-align: center; - gap: 20px; - } -} - -/* 手机端适配 (最大767px) */ -@media (max-width: 767px) { - .container { - padding: 15px; - max-width: 100%; - } - - .header { - padding: 25px 15px; - margin-bottom: 25px; - } - - .header h1 { - font-size: 2rem; - } - - .subtitle { - font-size: 1rem; - } - - .input-container, - .result-container { - padding: 25px; - border-radius: 15px; - } - - .main-content { - gap: 20px; - } - - .password-input { - padding: 16px 50px 16px 16px; - font-size: 1rem; - } - - .check-btn { - padding: 16px 28px; - font-size: 1rem; - } - - .strength-overview { - padding: 20px; - margin-bottom: 25px; - } - - .strength-score { - flex-direction: column; - text-align: center; - gap: 20px; - } - - .score-circle { - width: 100px; - height: 100px; - } - - .score-circle::before { - width: 75px; - height: 75px; - } - - .score-value { - font-size: 2rem; - } - - .strength-level { - font-size: 1.6rem; - } - - .details-grid { - grid-template-columns: 1fr; - gap: 20px; - } - - .detail-card { - padding: 20px; - } - - .character-types { - grid-template-columns: 1fr; - } - - .recommendations-section { - grid-template-columns: 1fr; - gap: 20px; - } - - .recommendations-card, - .security-tips-card { - padding: 20px; - } - - .toast { - right: 15px; - left: 15px; - top: 15px; - text-align: center; - } -} - -/* 小屏手机适配 (最大480px) */ -@media (max-width: 480px) { - .container { - padding: 10px; - } - - .header { - padding: 20px 10px; - margin-bottom: 20px; - } - - .header h1 { - font-size: 1.8rem; - } - - .input-container, - .result-container { - padding: 20px; - } - - .password-input { - padding: 14px 45px 14px 14px; - font-size: 0.95rem; - } - - .check-btn { - padding: 14px 24px; - } - - .detail-card { - padding: 15px; - } - - .card-header h3 { - font-size: 1.1rem; - } -} - -/* 触摸设备优化 */ -@media (hover: none) and (pointer: coarse) { - .check-btn, - .retry-btn, - .toggle-visibility { - min-height: 44px; - } - - .toggle-visibility { - padding: 12px; - } -} - -/* 高对比度模式支持 */ -@media (prefers-contrast: high) { - .input-container, - .result-container, - .detail-card { - border: 2px solid #2c3e50; - } - - .password-input { - border: 2px solid #2c3e50; - } -} - -/* 减少动画模式支持 */ -@media (prefers-reduced-motion: reduce) { - * { - animation-duration: 0.01ms !important; - animation-iteration-count: 1 !important; - transition-duration: 0.01ms !important; - } -} - -/* 深色模式支持 */ -@media (prefers-color-scheme: dark) { - body { - background: #0f172a; - color: #e2e8f0; - } - - .input-container, - .result-container, - .detail-card, - .recommendations-card, - .security-tips-card { - background: #1e293b; - border-color: #334155; - } - - .password-input { - background: #334155; - border-color: #475569; - color: #e2e8f0; - } - - .password-input:focus { - background: #1e293b; - border-color: #667eea; - } - - .strength-overview { - background: #1e293b; - border-color: #334155; - } - - .char-type, - .recommendations-list li, - .tip-item { - background: #334155; - border-color: #475569; - color: #e2e8f0; - } -} - -/* 打印样式 */ -@media print { - .header { - background: none !important; - color: black !important; - box-shadow: none !important; - } - - .check-btn, - .retry-btn, - .toggle-visibility, - .toast { - display: none !important; - } - - .input-container, - .result-container { - box-shadow: none !important; - border: 1px solid #ccc !important; - } -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/密码强度检测/index.html b/frontend/60sapi/实用功能/密码强度检测/index.html deleted file mode 100644 index f9b0c70a..00000000 --- a/frontend/60sapi/实用功能/密码强度检测/index.html +++ /dev/null @@ -1,218 +0,0 @@ - - - - - - - - 🔒 密码强度检测器 - - - - - - -
-
-

🔒 密码强度检测器

-

实时分析密码安全性,保护您的数字生活

-
- -
- -
-
- -
- - -
-
- 💡 - 输入密码后将实时显示安全性分析结果 -
-
- - -
- - - - - - -
- -
-

🔒 保护您的数字安全,从强密码开始

- -
-
- - - - - - - \ No newline at end of file diff --git a/frontend/60sapi/实用功能/密码强度检测/js/script.js b/frontend/60sapi/实用功能/密码强度检测/js/script.js deleted file mode 100644 index 8861664a..00000000 --- a/frontend/60sapi/实用功能/密码强度检测/js/script.js +++ /dev/null @@ -1,516 +0,0 @@ -/** - * 密码强度检测器 - * 提供密码强度分析和安全建议 - */ -class PasswordStrengthChecker { - constructor() { - this.apiUrl = 'https://60s.api.shumengya.top/v2/password/check'; - this.isChecking = false; - this.currentPassword = ''; - this.init(); - } - - /** - * 初始化应用 - */ - init() { - this.bindEvents(); - this.setupFormValidation(); - this.hideResultContainer(); - this.hideErrorContainer(); - console.log('密码强度检测器初始化完成'); - } - - /** - * 绑定事件监听器 - */ - bindEvents() { - // 密码输入框事件 - const passwordInput = document.getElementById('passwordInput'); - if (passwordInput) { - passwordInput.addEventListener('input', this.handlePasswordInput.bind(this)); - passwordInput.addEventListener('keypress', this.handleKeyPress.bind(this)); - } - - // 显示/隐藏密码按钮 - const toggleBtn = document.getElementById('toggleVisibility'); - if (toggleBtn) { - toggleBtn.addEventListener('click', this.togglePasswordVisibility.bind(this)); - } - - // 检测按钮 - const checkBtn = document.getElementById('checkBtn'); - if (checkBtn) { - checkBtn.addEventListener('click', this.handleCheckPassword.bind(this)); - } - - // 重试按钮 - const retryBtn = document.getElementById('retryBtn'); - if (retryBtn) { - retryBtn.addEventListener('click', this.handleRetry.bind(this)); - } - } - - /** - * 设置表单验证 - */ - setupFormValidation() { - const form = document.querySelector('.input-container'); - if (form) { - form.addEventListener('submit', (e) => { - e.preventDefault(); - this.handleCheckPassword(); - }); - } - } - - /** - * 处理密码输入 - */ - handlePasswordInput(event) { - const password = event.target.value; - this.currentPassword = password; - - // 更新按钮状态 - this.updateCheckButtonState(); - - // 如果密码为空,隐藏结果 - if (!password.trim()) { - this.hideResultContainer(); - this.hideErrorContainer(); - } - } - - /** - * 处理键盘事件 - */ - handleKeyPress(event) { - if (event.key === 'Enter' && !this.isChecking) { - event.preventDefault(); - this.handleCheckPassword(); - } - } - - /** - * 切换密码可见性 - */ - togglePasswordVisibility() { - const passwordInput = document.getElementById('passwordInput'); - const toggleBtn = document.getElementById('toggleVisibility'); - - if (passwordInput && toggleBtn) { - const isPassword = passwordInput.type === 'password'; - passwordInput.type = isPassword ? 'text' : 'password'; - toggleBtn.innerHTML = isPassword ? '🙈' : '👁️'; - toggleBtn.title = isPassword ? '隐藏密码' : '显示密码'; - } - } - - /** - * 更新检测按钮状态 - */ - updateCheckButtonState() { - const checkBtn = document.getElementById('checkBtn'); - const hasPassword = this.currentPassword.trim().length > 0; - - if (checkBtn) { - checkBtn.disabled = !hasPassword || this.isChecking; - - if (this.isChecking) { - checkBtn.innerHTML = '检测中...'; - } else if (hasPassword) { - checkBtn.innerHTML = '🔍检测密码强度'; - } else { - checkBtn.innerHTML = '🔍请输入密码'; - } - } - } - - /** - * 处理密码检测 - */ - async handleCheckPassword() { - const password = this.currentPassword.trim(); - - if (!password) { - this.showToast('请输入要检测的密码', 'error'); - return; - } - - if (this.isChecking) { - return; - } - - try { - this.setLoadingState(true); - this.hideErrorContainer(); - - const result = await this.checkPasswordStrength(password); - - if (result.code === 200 && result.data) { - this.displayResults(result.data); - this.showResultContainer(); - this.showToast('密码强度检测完成', 'success'); - } else { - throw new Error(result.message || '检测失败'); - } - } catch (error) { - console.error('密码检测错误:', error); - this.showError(error.message || '检测服务暂时不可用,请稍后重试'); - } finally { - this.setLoadingState(false); - } - } - - /** - * 调用API检测密码强度 - */ - async checkPasswordStrength(password) { - const url = new URL(this.apiUrl); - url.searchParams.append('password', password); - url.searchParams.append('encoding', 'utf-8'); - - const response = await fetch(url.toString(), { - method: 'GET', - headers: { - 'Accept': 'application/json', - 'Content-Type': 'application/json' - } - }); - - if (!response.ok) { - throw new Error(`HTTP ${response.status}: ${response.statusText}`); - } - - return await response.json(); - } - - /** - * 显示检测结果 - */ - displayResults(data) { - this.updateStrengthOverview(data); - this.updateDetailedInfo(data); - this.updateRecommendations(data); - } - - /** - * 更新强度概览 - */ - updateStrengthOverview(data) { - // 更新分数圆圈 - const scoreCircle = document.getElementById('scoreCircle'); - const scoreValue = document.getElementById('scoreValue'); - const strengthLevel = document.getElementById('strengthLevel'); - const strengthDescription = document.getElementById('strengthDescription'); - const barFill = document.getElementById('strengthBar'); - - if (scoreValue) { - scoreValue.textContent = data.score || 0; - } - - if (strengthLevel) { - strengthLevel.textContent = this.getStrengthText(data.strength); - const strengthClass = this.getStrengthClass(data.strength); - strengthLevel.className = `strength-level strength-${strengthClass}`; - } - - if (strengthDescription) { - strengthDescription.textContent = this.getStrengthDescription(data.strength); - } - - // 更新分数圆圈 - if (scoreCircle) { - const percentage = (data.score / 100) * 360; - scoreCircle.style.setProperty('--score-deg', `${percentage}deg`); - // 将中文强度转换为CSS类名 - const strengthClass = this.getStrengthClass(data.strength); - scoreCircle.className = `score-circle score-${strengthClass}`; - } - - // 更新强度条 - if (barFill) { - setTimeout(() => { - barFill.style.width = `${data.score}%`; - }, 100); - } - } - - /** - * 更新详细信息 - */ - updateDetailedInfo(data) { - // 基本信息 - this.updateElement('passwordLength', data.length || 0); - this.updateElement('entropyValue', data.entropy ? data.entropy.toFixed(2) : '0.00'); - this.updateElement('crackTime', data.time_to_crack || '未知'); - - // 字符类型分析 - this.updateCharacterAnalysis(data.character_analysis || {}); - } - - /** - * 更新字符类型分析 - */ - updateCharacterAnalysis(analysis) { - const types = { - 'has_lowercase': { element: 'hasLowercase', label: '小写字母', icon: '🔤' }, - 'has_uppercase': { element: 'hasUppercase', label: '大写字母', icon: '🔠' }, - 'has_numbers': { element: 'hasNumbers', label: '数字', icon: '🔢' }, - 'has_symbols': { element: 'hasSymbols', label: '特殊符号', icon: '🔣' } - }; - - Object.keys(types).forEach(key => { - const element = document.getElementById(types[key].element); - if (element) { - const hasType = analysis[key] || false; - element.className = `char-type ${hasType ? 'has-type' : ''}`; - element.innerHTML = ` - ${hasType ? '✅' : '❌'} - ${types[key].label} - `; - } - }); - - // 更新字符种类数量 - this.updateElement('characterVariety', analysis.character_variety || 0); - - // 更新问题提示 - this.updateCharacterIssues(analysis); - } - - /** - * 更新字符问题提示 - */ - updateCharacterIssues(analysis) { - const issues = [ - { id: 'hasRepeated', condition: analysis.has_repeated, text: '包含重复字符' }, - { id: 'hasSequential', condition: analysis.has_sequential, text: '包含连续字符' } - ]; - - issues.forEach(issue => { - const element = document.getElementById(issue.id); - if (element) { - if (issue.condition) { - element.style.display = 'flex'; - element.innerHTML = ` - ⚠️ - ${issue.text} - `; - } else { - element.style.display = 'none'; - } - } - }); - } - - /** - * 更新建议和提示 - */ - updateRecommendations(data) { - // 更新建议列表 - const recommendationsList = document.getElementById('recommendationsList'); - if (recommendationsList && data.recommendations) { - recommendationsList.innerHTML = ''; - data.recommendations.forEach(recommendation => { - const li = document.createElement('li'); - li.textContent = recommendation; - recommendationsList.appendChild(li); - }); - } - - // 更新安全提示 - const tipsContainer = document.getElementById('securityTips'); - if (tipsContainer && data.security_tips) { - tipsContainer.innerHTML = ''; - data.security_tips.forEach((tip, index) => { - const tipElement = document.createElement('div'); - tipElement.className = 'tip-item'; - tipElement.innerHTML = ` - ${this.getTipIcon(index)} - ${tip} - `; - tipsContainer.appendChild(tipElement); - }); - } - } - - /** - * 获取提示图标 - */ - getTipIcon(index) { - const icons = ['🛡️', '🔐', '⚡', '🎯', '💡', '🔄']; - return icons[index % icons.length]; - } - - /** - * 获取强度文本 - */ - getStrengthText(strength) { - // API直接返回中文强度,无需映射 - return strength || '未知'; - } - - /** - * 获取强度CSS类名 - */ - getStrengthClass(strength) { - const classMap = { - '弱': 'weak', - '中等': 'medium', - '强': 'strong', - '非常强': 'very-strong' - }; - return classMap[strength] || 'unknown'; - } - - /** - * 获取强度描述 - */ - getStrengthDescription(strength) { - const descriptions = { - '弱': '密码强度较弱,建议增加复杂度', - '中等': '密码强度中等,可以进一步优化', - '强': '密码强度良好,安全性较高', - '非常强': '密码强度非常好,安全性很高' - }; - return descriptions[strength] || '无法评估密码强度'; - } - - /** - * 设置加载状态 - */ - setLoadingState(loading) { - this.isChecking = loading; - this.updateCheckButtonState(); - - const passwordInput = document.getElementById('passwordInput'); - if (passwordInput) { - passwordInput.disabled = loading; - } - } - - /** - * 显示结果容器 - */ - showResultContainer() { - const container = document.getElementById('resultContainer'); - if (container) { - container.style.display = 'block'; - container.scrollIntoView({ behavior: 'smooth', block: 'start' }); - } - } - - /** - * 隐藏结果容器 - */ - hideResultContainer() { - const container = document.getElementById('resultContainer'); - if (container) { - container.style.display = 'none'; - } - } - - /** - * 显示错误 - */ - showError(message) { - const errorContainer = document.getElementById('errorContainer'); - const errorMessage = document.getElementById('errorMessage'); - - if (errorContainer && errorMessage) { - errorMessage.textContent = message; - errorContainer.style.display = 'block'; - this.hideResultContainer(); - errorContainer.scrollIntoView({ behavior: 'smooth', block: 'start' }); - } - } - - /** - * 隐藏错误容器 - */ - hideErrorContainer() { - const container = document.getElementById('errorContainer'); - if (container) { - container.style.display = 'none'; - } - } - - /** - * 处理重试 - */ - handleRetry() { - this.hideErrorContainer(); - const passwordInput = document.getElementById('passwordInput'); - if (passwordInput) { - passwordInput.focus(); - } - } - - /** - * 更新元素内容 - */ - updateElement(id, content) { - const element = document.getElementById(id); - if (element) { - element.textContent = content; - } - } - - /** - * 显示提示消息 - */ - showToast(message, type = 'success') { - const toast = document.getElementById('toast'); - const toastMessage = document.getElementById('toastMessage'); - - if (toast && toastMessage) { - toastMessage.textContent = message; - toast.className = `toast toast-${type}`; - toast.style.display = 'block'; - - // 3秒后自动隐藏 - setTimeout(() => { - toast.style.display = 'none'; - }, 3000); - } - } -} - -// 页面加载完成后初始化 -document.addEventListener('DOMContentLoaded', () => { - try { - window.passwordChecker = new PasswordStrengthChecker(); - console.log('密码强度检测器已启动'); - } catch (error) { - console.error('初始化失败:', error); - } -}); - -// 页面可见性变化处理 -document.addEventListener('visibilitychange', () => { - if (document.visibilityState === 'visible' && window.passwordChecker) { - console.log('页面重新激活'); - } -}); - -// 全局错误处理 -window.addEventListener('error', (event) => { - console.error('全局错误:', event.error); - if (window.passwordChecker) { - window.passwordChecker.showToast('发生了意外错误,请刷新页面重试', 'error'); - } -}); - -// 网络状态监听 -window.addEventListener('online', () => { - if (window.passwordChecker) { - window.passwordChecker.showToast('网络连接已恢复', 'success'); - } -}); - -window.addEventListener('offline', () => { - if (window.passwordChecker) { - window.passwordChecker.showToast('网络连接已断开', 'error'); - } -}); \ No newline at end of file diff --git a/frontend/60sapi/实用功能/密码强度检测/返回接口.json b/frontend/60sapi/实用功能/密码强度检测/返回接口.json deleted file mode 100644 index f9eba55a..00000000 --- a/frontend/60sapi/实用功能/密码强度检测/返回接口.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "code": 200, - "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", - "data": { - "password": "adasdasdasdadasd", - "length": 16, - "score": 68, - "strength": "中等", - "entropy": 75.21, - "time_to_crack": "数百万年", - "character_analysis": { - "has_lowercase": true, - "has_uppercase": false, - "has_numbers": false, - "has_symbols": false, - "has_repeated": false, - "has_sequential": true, - "character_variety": 26 - }, - "recommendations": [ - "建议包含大写字母", - "建议包含数字", - "建议包含特殊符号", - "避免使用连续序列字符" - ], - "security_tips": [ - "使用密码管理器生成和存储复杂密码", - "为不同账户使用不同的密码", - "定期更换重要账户的密码", - "启用双因素认证(2FA)增强安全性", - "避免在公共场合输入密码", - "不要将密码保存在浏览器中(除非使用可信的密码管理器)", - "避免使用个人信息作为密码", - "长密码比复杂密码更安全" - ] - } -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/生成二维码/css/background.css b/frontend/60sapi/实用功能/生成二维码/css/background.css deleted file mode 100755 index f0cd4e04..00000000 --- a/frontend/60sapi/实用功能/生成二维码/css/background.css +++ /dev/null @@ -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%); - } -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/生成二维码/css/style.css b/frontend/60sapi/实用功能/生成二维码/css/style.css deleted file mode 100755 index ca4dd96c..00000000 --- a/frontend/60sapi/实用功能/生成二维码/css/style.css +++ /dev/null @@ -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%; - } -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/生成二维码/index.html b/frontend/60sapi/实用功能/生成二维码/index.html deleted file mode 100755 index f9366891..00000000 --- a/frontend/60sapi/实用功能/生成二维码/index.html +++ /dev/null @@ -1,98 +0,0 @@ - - - - - - 二维码生成器 - - - - -
-
-

🔗 二维码生成器

-

快速生成高质量二维码

-
- -
-
-
-
- - -
- -
-
- - -
- -
- - -
- -
- - -
-
- - -
-
- -
- - - - - -
-
- -
-

© 2024 二维码生成器 - 简单快捷的二维码生成工具

-
-
- - - - \ No newline at end of file diff --git a/frontend/60sapi/实用功能/生成二维码/js/script.js b/frontend/60sapi/实用功能/生成二维码/js/script.js deleted file mode 100755 index 1b17ffe6..00000000 --- a/frontend/60sapi/实用功能/生成二维码/js/script.js +++ /dev/null @@ -1,453 +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 { - // 直接在代码中配置API接口,避免CORS问题 - this.apiEndpoints = [ - "https://60s.api.shumengya.top" - ]; - 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'); - const textArea = document.getElementById('text'); - - if (form) { - form.addEventListener('submit', (e) => this.handleSubmit(e)); - } - if (retryBtn) { - retryBtn.addEventListener('click', () => this.retryGeneration()); - } - if (downloadBtn) { - downloadBtn.addEventListener('click', () => this.downloadQRCode()); - } - if (copyBtn) { - copyBtn.addEventListener('click', () => this.copyImageLink()); - } - if (newBtn) { - newBtn.addEventListener('click', () => this.resetForm()); - } - if (textArea) { - 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 !== null && value !== undefined && 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' || !params.encoding) { - // 默认返回图片格式 - const contentType = response.headers.get('content-type'); - if (contentType && contentType.startsWith('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 { - // 如果返回的不是图片,尝试解析JSON - const jsonData = await response.json(); - if (jsonData.code === 0 && jsonData.data && jsonData.data.data_uri) { - 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 || '生成失败'); - } - } - } else { - // JSON或text格式 - 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: params.encoding, - 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 = ` - 内容: ${this.escapeHtml(data.text)}
- 尺寸: ${data.size}x${data.size}
- 容错级别: ${data.level}
- 格式: ${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); -}); \ No newline at end of file diff --git a/frontend/60sapi/实用功能/生成二维码/接口集合.json b/frontend/60sapi/实用功能/生成二维码/接口集合.json deleted file mode 100755 index 547b2771..00000000 --- a/frontend/60sapi/实用功能/生成二维码/接口集合.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "https://60s.api.shumengya.top" -] diff --git a/frontend/60sapi/实用功能/百度百科词条/css/background.css b/frontend/60sapi/实用功能/百度百科词条/css/background.css deleted file mode 100755 index 04fcd858..00000000 --- a/frontend/60sapi/实用功能/百度百科词条/css/background.css +++ /dev/null @@ -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%; - } -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/百度百科词条/css/style.css b/frontend/60sapi/实用功能/百度百科词条/css/style.css deleted file mode 100755 index 8de2ae2c..00000000 --- a/frontend/60sapi/实用功能/百度百科词条/css/style.css +++ /dev/null @@ -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; - } -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/百度百科词条/index.html b/frontend/60sapi/实用功能/百度百科词条/index.html deleted file mode 100755 index 6b52b446..00000000 --- a/frontend/60sapi/实用功能/百度百科词条/index.html +++ /dev/null @@ -1,83 +0,0 @@ - - - - - - 百度百科词条查询 - - - - -
-
-

百度百科词条查询

-

探索知识的彩虹世界

-
- -
-
-
- - -
-
- -
- - - - - - -
-
📚
-

欢迎使用百度百科词条查询

-

在上方搜索框中输入您想了解的词条,开始探索知识的海洋

-
-
-
- -
-

数据来源:百度百科

-
-
- - - - \ No newline at end of file diff --git a/frontend/60sapi/实用功能/百度百科词条/js/script.js b/frontend/60sapi/实用功能/百度百科词条/js/script.js deleted file mode 100755 index 20a423bf..00000000 --- a/frontend/60sapi/实用功能/百度百科词条/js/script.js +++ /dev/null @@ -1,320 +0,0 @@ -// 百度百科词条查询应用 -class BaikeApp { - constructor() { - // API接口列表 - this.apiEndpoints = [ - 'https://60s.api.shumengya.top', - ]; - - 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('百度百科词条查询应用已初始化'); -}); \ No newline at end of file diff --git a/frontend/60sapi/实用功能/百度百科词条/接口集合.json b/frontend/60sapi/实用功能/百度百科词条/接口集合.json deleted file mode 100755 index 547b2771..00000000 --- a/frontend/60sapi/实用功能/百度百科词条/接口集合.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "https://60s.api.shumengya.top" -] diff --git a/frontend/60sapi/实用功能/百度百科词条/返回接口.json b/frontend/60sapi/实用功能/百度百科词条/返回接口.json deleted file mode 100755 index 55ec21dc..00000000 --- a/frontend/60sapi/实用功能/百度百科词条/返回接口.json +++ /dev/null @@ -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" - } -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/身体健康分析/background.css b/frontend/60sapi/实用功能/身体健康分析/background.css deleted file mode 100644 index 9eb864ab..00000000 --- a/frontend/60sapi/实用功能/身体健康分析/background.css +++ /dev/null @@ -1,243 +0,0 @@ -/* 背景样式文件 - 独立管理背景相关样式 */ - -/* 主体背景 */ -body { - background: linear-gradient(135deg, #e8f5e8 0%, #f0f8f0 25%, #e1f5e1 50%, #f5f9f5 75%, #e8f5e8 100%); - 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(144, 238, 144, 0.1) 0%, transparent 50%), - radial-gradient(circle at 80% 20%, rgba(152, 251, 152, 0.1) 0%, transparent 50%), - radial-gradient(circle at 40% 40%, rgba(173, 255, 173, 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.3), transparent), - radial-gradient(1px 1px at 90px 40px, rgba(165, 214, 167, 0.3), transparent), - radial-gradient(1px 1px at 130px 80px, rgba(200, 230, 201, 0.3), transparent), - radial-gradient(2px 2px at 160px 30px, rgba(76, 175, 80, 0.2), 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); - } -} - -/* 容器背景增强 */ -.container { - background: rgba(255, 255, 255, 0.02); - backdrop-filter: blur(10px); - border-radius: 20px; - position: relative; -} - -/* 表单区域背景 */ -.form-section { - background: rgba(255, 255, 255, 0.95); - backdrop-filter: blur(20px); - border: 1px solid rgba(144, 238, 144, 0.3); - position: relative; - overflow: hidden; -} - -.form-section::before { - content: ''; - position: absolute; - top: -50%; - left: -50%; - width: 200%; - height: 200%; - background: linear-gradient(45deg, transparent, rgba(144, 238, 144, 0.05), transparent); - animation: shimmer 3s ease-in-out infinite; - pointer-events: none; -} - -@keyframes shimmer { - 0% { - transform: translateX(-100%) translateY(-100%) rotate(45deg); - } - 50% { - transform: translateX(100%) translateY(100%) rotate(45deg); - } - 100% { - transform: translateX(-100%) translateY(-100%) rotate(45deg); - } -} - -/* 结果卡片背景 */ -.basic-info-card, -.bmi-card, -.weight-card, -.metabolism-card, -.body-fat-card, -.measurements-card, -.advice-card { - background: rgba(255, 255, 255, 0.95); - backdrop-filter: blur(15px); - border: 1px solid rgba(144, 238, 144, 0.2); - position: relative; - overflow: hidden; -} - -/* 卡片悬停背景效果 */ -.basic-info-card:hover, -.bmi-card:hover, -.weight-card:hover, -.metabolism-card:hover, -.body-fat-card:hover, -.measurements-card:hover, -.advice-card:hover { - background: rgba(255, 255, 255, 0.98); - border-color: rgba(76, 175, 80, 0.4); -} - -/* 免责声明卡片背景 */ -.disclaimer-card { - background: rgba(255, 243, 205, 0.95); - backdrop-filter: blur(15px); - border: 1px solid rgba(255, 234, 167, 0.5); -} - -/* 错误区域背景 */ -.error-content { - background: rgba(255, 255, 255, 0.95); - backdrop-filter: blur(20px); - border: 1px solid rgba(220, 53, 69, 0.2); -} - -/* 输入框背景 */ -.form-input, -.form-select { - background: rgba(248, 255, 248, 0.9); - backdrop-filter: blur(10px); -} - -.form-input:focus, -.form-select:focus { - background: rgba(255, 255, 255, 0.95); - backdrop-filter: blur(15px); -} - -/* 信息项背景 */ -.info-item { - background: rgba(248, 255, 248, 0.8); - backdrop-filter: blur(5px); -} - -/* BMI分类背景 */ -.bmi-category { - background: rgba(232, 245, 232, 0.9); - backdrop-filter: blur(10px); -} - -/* 健康建议列表项背景 */ -.health-tips li { - background: rgba(248, 255, 248, 0.8); - backdrop-filter: blur(5px); -} - -/* 按钮背景增强 */ -.submit-btn { - position: relative; - overflow: hidden; -} - -.submit-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; -} - -.submit-btn:hover::before { - left: 100%; -} - -/* 重置按钮背景 */ -.reset-btn { - background: rgba(232, 245, 232, 0.9); - backdrop-filter: blur(10px); -} - -.reset-btn:hover { - background: rgba(212, 237, 218, 0.95); -} - -/* 响应式背景调整 */ -@media (max-width: 767px) { - body::after { - background-size: 150px 75px; - animation-duration: 15s; - } - - .form-section::before { - animation-duration: 2s; - } -} - -@media (min-width: 768px) and (max-width: 1024px) { - body::after { - background-size: 180px 90px; - animation-duration: 18s; - } -} - -@media (min-width: 1024px) { - body::after { - background-size: 220px 110px; - animation-duration: 25s; - } - - .container { - background: rgba(255, 255, 255, 0.05); - } -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/身体健康分析/index.html b/frontend/60sapi/实用功能/身体健康分析/index.html deleted file mode 100644 index d34d508c..00000000 --- a/frontend/60sapi/实用功能/身体健康分析/index.html +++ /dev/null @@ -1,115 +0,0 @@ - - - - - - 身体健康分析 - - - - -
-
-

身体健康分析

-

通过身高、体重、年龄、性别多维度分析身体健康状态

-
- -
-
-
-
- - -
- -
- - -
- -
- - -
- -
- - -
- - -
-
- - - - -
- -
- -
-
- - - - \ No newline at end of file diff --git a/frontend/60sapi/实用功能/身体健康分析/script.js b/frontend/60sapi/实用功能/身体健康分析/script.js deleted file mode 100644 index d0a440df..00000000 --- a/frontend/60sapi/实用功能/身体健康分析/script.js +++ /dev/null @@ -1,515 +0,0 @@ -// 身体健康分析 JavaScript 功能 - -// DOM 元素获取 -const healthForm = document.getElementById('healthForm'); -const analyzeBtn = document.getElementById('analyzeBtn'); -const btnText = analyzeBtn.querySelector('.btn-text'); -const loadingSpinner = analyzeBtn.querySelector('.loading-spinner'); -const resultSection = document.getElementById('resultSection'); -const errorSection = document.getElementById('errorSection'); -const resetBtn = document.getElementById('resetBtn'); -const retryBtn = document.getElementById('retryBtn'); - -// API 配置 -const API_BASE_URL = 'https://60s.api.shumengya.top/v2/health'; - -// 表单验证规则 -const validationRules = { - height: { - min: 100, - max: 250, - message: '身高应在100-250cm之间' - }, - weight: { - min: 30, - max: 200, - message: '体重应在30-200kg之间' - }, - age: { - min: 1, - max: 120, - message: '年龄应在1-120岁之间' - } -}; - -// 初始化 -document.addEventListener('DOMContentLoaded', function() { - initializeEventListeners(); - setupFormValidation(); -}); - -// 事件监听器初始化 -function initializeEventListeners() { - healthForm.addEventListener('submit', handleFormSubmit); - resetBtn.addEventListener('click', resetForm); - retryBtn.addEventListener('click', retryAnalysis); - - // 输入框实时验证 - const inputs = healthForm.querySelectorAll('input, select'); - inputs.forEach(input => { - input.addEventListener('blur', validateField); - input.addEventListener('input', clearFieldError); - }); -} - -// 表单验证设置 -function setupFormValidation() { - const inputs = healthForm.querySelectorAll('input[type="number"]'); - inputs.forEach(input => { - input.addEventListener('input', function() { - // 移除非数字字符 - this.value = this.value.replace(/[^0-9.]/g, ''); - - // 防止多个小数点 - const parts = this.value.split('.'); - if (parts.length > 2) { - this.value = parts[0] + '.' + parts.slice(1).join(''); - } - }); - }); -} - -// 表单提交处理 -async function handleFormSubmit(event) { - event.preventDefault(); - - if (!validateForm()) { - return; - } - - const formData = getFormData(); - - try { - setLoadingState(true); - hideAllSections(); - - const result = await callHealthAPI(formData); - displayResults(result); - - } catch (error) { - console.error('分析失败:', error); - displayError(error.message || '分析失败,请稍后重试'); - } finally { - setLoadingState(false); - } -} - -// 获取表单数据 -function getFormData() { - return { - height: parseInt(document.getElementById('height').value), - weight: parseInt(document.getElementById('weight').value), - age: parseInt(document.getElementById('age').value), - gender: document.getElementById('gender').value - }; -} - -// 表单验证 -function validateForm() { - let isValid = true; - const inputs = healthForm.querySelectorAll('input, select'); - - inputs.forEach(input => { - if (!validateField({ target: input })) { - isValid = false; - } - }); - - return isValid; -} - -// 单个字段验证 -function validateField(event) { - const field = event.target; - const value = field.value.trim(); - const fieldName = field.name; - - // 清除之前的错误状态 - clearFieldError(event); - - // 必填验证 - if (!value) { - showFieldError(field, '此字段为必填项'); - return false; - } - - // 数值范围验证 - if (validationRules[fieldName]) { - const numValue = parseFloat(value); - const rule = validationRules[fieldName]; - - if (numValue < rule.min || numValue > rule.max) { - showFieldError(field, rule.message); - return false; - } - } - - return true; -} - -// 显示字段错误 -function showFieldError(field, message) { - field.classList.add('error'); - - // 移除已存在的错误消息 - const existingError = field.parentNode.querySelector('.error-message'); - if (existingError) { - existingError.remove(); - } - - // 添加错误消息 - const errorDiv = document.createElement('div'); - errorDiv.className = 'error-message'; - errorDiv.textContent = message; - errorDiv.style.color = '#dc3545'; - errorDiv.style.fontSize = '0.875rem'; - errorDiv.style.marginTop = '5px'; - - field.parentNode.appendChild(errorDiv); -} - -// 清除字段错误 -function clearFieldError(event) { - const field = event.target; - field.classList.remove('error'); - - const errorMessage = field.parentNode.querySelector('.error-message'); - if (errorMessage) { - errorMessage.remove(); - } -} - -// 调用健康分析API -async function callHealthAPI(data) { - const params = new URLSearchParams({ - height: data.height, - weight: data.weight, - age: data.age, - gender: data.gender - }); - - const response = await fetch(`${API_BASE_URL}?${params}`); - - if (!response.ok) { - throw new Error(`HTTP ${response.status}: ${response.statusText}`); - } - - const result = await response.json(); - - if (result.code !== 200) { - throw new Error(result.message || '分析失败'); - } - - return result.data; -} - -// 显示分析结果 -function displayResults(data) { - // 基本信息 - displayBasicInfo(data.basic_info); - - // BMI 分析 - displayBMIInfo(data.bmi); - - // 体重评估 - displayWeightAssessment(data.weight_assessment); - - // 代谢分析 - displayMetabolism(data.metabolism); - - // 体脂分析 - displayBodyFat(data.body_fat); - - // 理想三围 - displayMeasurements(data.ideal_measurements); - - // 健康建议 - displayHealthAdvice(data.health_advice); - - // 免责声明 - displayDisclaimer(data.disclaimer); - - // 显示结果区域 - resultSection.style.display = 'block'; - resultSection.scrollIntoView({ behavior: 'smooth' }); -} - -// 显示基本信息 -function displayBasicInfo(basicInfo) { - const container = document.getElementById('basicInfo'); - container.innerHTML = ''; - - const infoItems = [ - { label: basicInfo.height_desc, value: basicInfo.height }, - { label: basicInfo.weight_desc, value: basicInfo.weight }, - { label: basicInfo.age_desc, value: basicInfo.age }, - { label: basicInfo.gender_desc, value: basicInfo.gender } - ]; - - infoItems.forEach(item => { - const itemDiv = createInfoItem(item.label, item.value); - container.appendChild(itemDiv); - }); -} - -// 显示BMI信息 -function displayBMIInfo(bmiData) { - const container = document.getElementById('bmiContent'); - container.innerHTML = ` -
${bmiData.value}
-
${bmiData.category}
-
- ${createInfoItem(bmiData.evaluation_desc, bmiData.evaluation).outerHTML} - ${createInfoItem(bmiData.risk_desc, bmiData.risk).outerHTML} -
- `; -} - -// 显示体重评估 -function displayWeightAssessment(weightData) { - const container = document.getElementById('weightContent'); - container.innerHTML = ''; - - const items = [ - { label: weightData.ideal_weight_range_desc, value: weightData.ideal_weight_range }, - { label: weightData.standard_weight_desc, value: weightData.standard_weight }, - { label: weightData.status_desc, value: weightData.status }, - { label: weightData.adjustment_desc, value: weightData.adjustment } - ]; - - const grid = document.createElement('div'); - grid.className = 'info-grid'; - - items.forEach(item => { - const itemDiv = createInfoItem(item.label, item.value); - grid.appendChild(itemDiv); - }); - - container.appendChild(grid); -} - -// 显示代谢分析 -function displayMetabolism(metabolismData) { - const container = document.getElementById('metabolismContent'); - container.innerHTML = ''; - - const items = [ - { label: metabolismData.bmr_desc, value: metabolismData.bmr }, - { label: metabolismData.tdee_desc, value: metabolismData.tdee }, - { label: metabolismData.recommended_calories_desc, value: metabolismData.recommended_calories }, - { label: metabolismData.weight_loss_calories_desc, value: metabolismData.weight_loss_calories }, - { label: metabolismData.weight_gain_calories_desc, value: metabolismData.weight_gain_calories } - ]; - - const grid = document.createElement('div'); - grid.className = 'info-grid'; - - items.forEach(item => { - const itemDiv = createInfoItem(item.label, item.value); - grid.appendChild(itemDiv); - }); - - container.appendChild(grid); -} - -// 显示体脂分析 -function displayBodyFat(bodyFatData) { - const container = document.getElementById('bodyFatContent'); - container.innerHTML = ''; - - const items = [ - { label: bodyFatData.percentage_desc, value: bodyFatData.percentage }, - { label: bodyFatData.category_desc, value: bodyFatData.category }, - { label: bodyFatData.fat_weight_desc, value: bodyFatData.fat_weight }, - { label: bodyFatData.lean_weight_desc, value: bodyFatData.lean_weight } - ]; - - const grid = document.createElement('div'); - grid.className = 'info-grid'; - - items.forEach(item => { - const itemDiv = createInfoItem(item.label, item.value); - grid.appendChild(itemDiv); - }); - - container.appendChild(grid); -} - -// 显示理想三围 -function displayMeasurements(measurementsData) { - const container = document.getElementById('measurementsContent'); - container.innerHTML = ''; - - const items = [ - { label: measurementsData.chest_desc, value: measurementsData.chest }, - { label: measurementsData.waist_desc, value: measurementsData.waist }, - { label: measurementsData.hip_desc, value: measurementsData.hip } - ]; - - const grid = document.createElement('div'); - grid.className = 'info-grid'; - - items.forEach(item => { - const itemDiv = createInfoItem(item.label, item.value); - grid.appendChild(itemDiv); - }); - - // 添加说明 - const note = document.createElement('p'); - note.style.marginTop = '15px'; - note.style.fontSize = '0.9rem'; - note.style.color = '#4a7c59'; - note.style.textAlign = 'center'; - note.textContent = measurementsData.note; - - container.appendChild(grid); - container.appendChild(note); -} - -// 显示健康建议 -function displayHealthAdvice(adviceData) { - const container = document.getElementById('adviceContent'); - container.innerHTML = ''; - - // 饮水量建议 - const waterDiv = createAdviceSection(adviceData.daily_water_intake_desc, adviceData.daily_water_intake); - container.appendChild(waterDiv); - - // 运动建议 - const exerciseDiv = createAdviceSection(adviceData.exercise_recommendation_desc, adviceData.exercise_recommendation); - container.appendChild(exerciseDiv); - - // 营养建议 - const nutritionDiv = createAdviceSection(adviceData.nutrition_advice_desc, adviceData.nutrition_advice); - container.appendChild(nutritionDiv); - - // 健康提示 - const tipsDiv = document.createElement('div'); - tipsDiv.innerHTML = ` -

${adviceData.health_tips_desc}

-
    - `; - - const tipsList = tipsDiv.querySelector('.health-tips'); - adviceData.health_tips.forEach(tip => { - const li = document.createElement('li'); - li.textContent = tip; - tipsList.appendChild(li); - }); - - container.appendChild(tipsDiv); -} - -// 创建建议区块 -function createAdviceSection(title, content) { - const div = document.createElement('div'); - div.style.marginBottom = '20px'; - div.innerHTML = ` -

    ${title}

    -

    ${content}

    - `; - return div; -} - -// 显示免责声明 -function displayDisclaimer(disclaimer) { - const container = document.getElementById('disclaimer'); - container.textContent = disclaimer; -} - -// 创建信息项 -function createInfoItem(label, value) { - const div = document.createElement('div'); - div.className = 'info-item'; - div.innerHTML = ` -
    ${label}
    -
    ${value}
    - `; - return div; -} - -// 显示错误信息 -function displayError(message) { - const errorMessage = document.getElementById('errorMessage'); - errorMessage.textContent = message; - errorSection.style.display = 'block'; - errorSection.scrollIntoView({ behavior: 'smooth' }); -} - -// 设置加载状态 -function setLoadingState(isLoading) { - if (isLoading) { - analyzeBtn.disabled = true; - btnText.style.display = 'none'; - loadingSpinner.style.display = 'block'; - } else { - analyzeBtn.disabled = false; - btnText.style.display = 'block'; - loadingSpinner.style.display = 'none'; - } -} - -// 隐藏所有结果区域 -function hideAllSections() { - resultSection.style.display = 'none'; - errorSection.style.display = 'none'; -} - -// 重置表单 -function resetForm() { - healthForm.reset(); - hideAllSections(); - - // 清除所有错误状态 - const errorInputs = healthForm.querySelectorAll('.error'); - errorInputs.forEach(input => { - input.classList.remove('error'); - }); - - const errorMessages = healthForm.querySelectorAll('.error-message'); - errorMessages.forEach(msg => msg.remove()); - - // 滚动到表单顶部 - healthForm.scrollIntoView({ behavior: 'smooth' }); -} - -// 重试分析 -function retryAnalysis() { - hideAllSections(); - healthForm.scrollIntoView({ behavior: 'smooth' }); -} - -// 工具函数:防抖 -function debounce(func, wait) { - let timeout; - return function executedFunction(...args) { - const later = () => { - clearTimeout(timeout); - func(...args); - }; - clearTimeout(timeout); - timeout = setTimeout(later, wait); - }; -} - -// 添加CSS样式到错误输入框 -const style = document.createElement('style'); -style.textContent = ` - .form-input.error, - .form-select.error { - border-color: #dc3545 !important; - box-shadow: 0 0 0 3px rgba(220, 53, 69, 0.1) !important; - } -`; -document.head.appendChild(style); - -// 页面可见性变化处理(用户切换标签页时暂停动画等) -document.addEventListener('visibilitychange', function() { - if (document.hidden) { - // 页面隐藏时的处理 - document.body.style.animationPlayState = 'paused'; - } else { - // 页面显示时的处理 - document.body.style.animationPlayState = 'running'; - } -}); \ No newline at end of file diff --git a/frontend/60sapi/实用功能/身体健康分析/styles.css b/frontend/60sapi/实用功能/身体健康分析/styles.css deleted file mode 100644 index 90fde65a..00000000 --- a/frontend/60sapi/实用功能/身体健康分析/styles.css +++ /dev/null @@ -1,697 +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: #2d5a3d; - min-height: 100vh; -} - -/* 容器布局 */ -.container { - max-width: 1200px; - margin: 0 auto; - padding: 20px; - min-height: 100vh; - display: flex; - flex-direction: column; -} - -/* 头部样式 */ -.header { - text-align: center; - margin-bottom: 30px; - padding: 20px 0; -} - -.title { - font-size: 2.5rem; - font-weight: 700; - color: #1a4d2e; - margin-bottom: 10px; - text-shadow: 0 2px 4px rgba(26, 77, 46, 0.1); -} - -.subtitle { - font-size: 1.1rem; - color: #4a7c59; - font-weight: 400; -} - -/* 主内容区域 */ -.main-content { - flex: 1; - display: flex; - flex-direction: column; - gap: 30px; -} - -/* 表单区域 */ -.form-section { - background: rgba(255, 255, 255, 0.95); - border-radius: 20px; - padding: 30px; - box-shadow: 0 8px 32px rgba(26, 77, 46, 0.1); - border: 1px solid rgba(144, 238, 144, 0.3); -} - -.health-form { - display: grid; - gap: 20px; -} - -.form-group { - display: flex; - flex-direction: column; - gap: 8px; -} - -.form-label { - font-weight: 600; - color: #2d5a3d; - font-size: 1rem; -} - -.form-input, -.form-select { - padding: 15px 20px; - border: 2px solid #a8e6a3; - border-radius: 12px; - font-size: 1rem; - background: #f8fff8; - color: #2d5a3d; - transition: all 0.3s ease; -} - -.form-input:focus, -.form-select:focus { - outline: none; - border-color: #4caf50; - box-shadow: 0 0 0 3px rgba(76, 175, 80, 0.1); - background: #ffffff; -} - -.form-input::placeholder { - color: #81c784; -} - -/* 提交按钮 */ -.submit-btn { - background: linear-gradient(135deg, #4caf50, #66bb6a); - color: white; - border: none; - padding: 18px 30px; - border-radius: 12px; - font-size: 1.1rem; - font-weight: 600; - cursor: pointer; - transition: all 0.3s ease; - position: relative; - overflow: hidden; - margin-top: 10px; -} - -.submit-btn:hover { - background: linear-gradient(135deg, #45a049, #5cb85c); - transform: translateY(-2px); - box-shadow: 0 8px 25px rgba(76, 175, 80, 0.3); -} - -.submit-btn:active { - transform: translateY(0); -} - -.submit-btn:disabled { - background: #c8e6c9; - cursor: not-allowed; - transform: none; - box-shadow: none; -} - -/* 加载动画 */ -.loading-spinner { - width: 20px; - height: 20px; - border: 2px solid rgba(255, 255, 255, 0.3); - border-top: 2px solid white; - border-radius: 50%; - animation: spin 1s linear infinite; - margin: 0 auto; -} - -@keyframes spin { - 0% { transform: rotate(0deg); } - 100% { transform: rotate(360deg); } -} - -/* 结果区域 */ -.result-section { - animation: fadeInUp 0.6s ease-out; -} - -.result-header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 25px; - flex-wrap: wrap; - gap: 15px; -} - -.result-title { - font-size: 2rem; - color: #1a4d2e; - font-weight: 700; -} - -.reset-btn { - background: #e8f5e8; - color: #2d5a3d; - border: 2px solid #a8e6a3; - padding: 10px 20px; - border-radius: 8px; - font-weight: 600; - cursor: pointer; - transition: all 0.3s ease; -} - -.reset-btn:hover { - background: #d4edda; - border-color: #4caf50; -} - -/* 结果卡片 */ -.result-content { - display: grid; - gap: 20px; -} - -.basic-info-card, -.bmi-card, -.weight-card, -.metabolism-card, -.body-fat-card, -.measurements-card, -.advice-card, -.disclaimer-card { - background: rgba(255, 255, 255, 0.95); - border-radius: 16px; - padding: 25px; - box-shadow: 0 6px 20px rgba(26, 77, 46, 0.08); - border: 1px solid rgba(144, 238, 144, 0.2); - transition: transform 0.3s ease, box-shadow 0.3s ease; -} - -.basic-info-card:hover, -.bmi-card:hover, -.weight-card:hover, -.metabolism-card:hover, -.body-fat-card:hover, -.measurements-card:hover, -.advice-card:hover { - transform: translateY(-2px); - box-shadow: 0 8px 25px rgba(26, 77, 46, 0.12); -} - -.card-title { - font-size: 1.4rem; - color: #1a4d2e; - font-weight: 700; - margin-bottom: 15px; - border-bottom: 2px solid #e8f5e8; - padding-bottom: 10px; -} - -/* 信息网格 */ -.info-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); - gap: 15px; -} - -.info-item { - background: #f8fff8; - padding: 15px; - border-radius: 10px; - border-left: 4px solid #4caf50; -} - -.info-label { - font-size: 0.9rem; - color: #4a7c59; - font-weight: 600; - margin-bottom: 5px; -} - -.info-value { - font-size: 1.2rem; - color: #2d5a3d; - font-weight: 700; -} - -/* BMI 特殊样式 */ -.bmi-value { - font-size: 2.5rem; - font-weight: 800; - color: #4caf50; - text-align: center; - margin: 15px 0; -} - -.bmi-category { - text-align: center; - font-size: 1.3rem; - font-weight: 600; - color: #2d5a3d; - background: #e8f5e8; - padding: 10px; - border-radius: 8px; - margin: 10px 0; -} - -/* 健康建议列表 */ -.health-tips { - list-style: none; - padding: 0; -} - -.health-tips li { - background: #f8fff8; - margin: 10px 0; - padding: 12px 15px; - border-radius: 8px; - border-left: 4px solid #81c784; - position: relative; -} - -.health-tips li::before { - content: "✓"; - color: #4caf50; - font-weight: bold; - margin-right: 10px; -} - -/* 免责声明 */ -.disclaimer { - background: #fff3cd; - border: 1px solid #ffeaa7; - color: #856404; - padding: 15px; - border-radius: 8px; - font-size: 0.95rem; - line-height: 1.5; - text-align: center; -} - -/* 错误区域 */ -.error-section { - text-align: center; - padding: 40px 20px; -} - -.error-content { - background: rgba(255, 255, 255, 0.95); - border-radius: 16px; - padding: 30px; - box-shadow: 0 6px 20px rgba(220, 53, 69, 0.1); - border: 1px solid rgba(220, 53, 69, 0.2); - max-width: 400px; - margin: 0 auto; -} - -.error-title { - color: #dc3545; - font-size: 1.5rem; - margin-bottom: 15px; -} - -.error-message { - color: #6c757d; - margin-bottom: 20px; -} - -.retry-btn { - background: #dc3545; - color: white; - border: none; - padding: 12px 24px; - border-radius: 8px; - font-weight: 600; - cursor: pointer; - transition: background 0.3s ease; -} - -.retry-btn:hover { - background: #c82333; -} - -/* 底部 */ -.footer { - text-align: center; - padding: 20px 0; - margin-top: 30px; - border-top: 1px solid rgba(144, 238, 144, 0.3); -} - -.footer-text { - color: #4a7c59; - font-size: 0.9rem; -} - -/* 动画效果 */ -@keyframes fadeInUp { - from { - opacity: 0; - transform: translateY(30px); - } - to { - opacity: 1; - transform: translateY(0); - } -} - -/* 平板端适配 (768px - 1024px) */ -@media (min-width: 768px) and (max-width: 1024px) { - .container { - padding: 30px; - } - - .title { - font-size: 2.8rem; - } - - .form-section { - padding: 35px; - } - - .health-form { - grid-template-columns: repeat(2, 1fr); - gap: 25px; - } - - .form-group:last-child { - grid-column: 1 / -1; - } - - .result-content { - grid-template-columns: repeat(2, 1fr); - } - - .advice-card, - .disclaimer-card { - grid-column: 1 / -1; - } -} - -/* 电脑端适配 (1024px+) */ -@media (min-width: 1024px) { - .container { - padding: 40px; - max-width: 1400px; - } - - .title { - font-size: 3.2rem; - } - - .main-content { - flex-direction: row; - gap: 40px; - align-items: flex-start; - } - - .form-section { - flex: 0 0 380px; - position: sticky; - top: 20px; - max-height: calc(100vh - 40px); - overflow-y: auto; - } - - .result-section, - .error-section { - flex: 1; - min-width: 0; - } - - /* 桌面端结果区域重新设计 - 使用更清晰的布局 */ - .result-content { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 25px; - grid-auto-rows: min-content; - } - - /* 基本信息卡片 - 占满第一行 */ - .basic-info-card { - grid-column: 1 / -1; - } - - /* 第二行:BMI、体重评估、代谢分析 */ - .bmi-card, - .weight-card, - .metabolism-card { - grid-column: span 1; - } - - /* 第三行:体脂分析和理想三围 */ - .body-fat-card { - grid-column: span 2; - } - - .measurements-card { - grid-column: span 1; - } - - /* 第四行:健康建议 - 占满整行 */ - .advice-card { - grid-column: 1 / -1; - } - - /* 第五行:免责声明 - 占满整行 */ - .disclaimer-card { - grid-column: 1 / -1; - } - - /* 基本信息网格优化 */ - .basic-info-card .info-grid { - grid-template-columns: repeat(4, 1fr); - gap: 20px; - } - - /* BMI卡片特殊布局 */ - .bmi-card { - display: flex; - flex-direction: column; - min-height: 280px; - } - - .bmi-card .bmi-content { - flex: 1; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - text-align: center; - } - - .bmi-value { - font-size: 3rem; - margin: 20px 0; - } - - /* 体重评估卡片布局优化 */ - .weight-card { - display: flex; - flex-direction: column; - min-height: 280px; - } - - .weight-card .weight-content { - flex: 1; - display: flex; - flex-direction: column; - justify-content: space-between; - } - - .weight-card .info-grid { - grid-template-columns: 1fr; - gap: 12px; - } - - /* 代谢分析卡片布局优化 */ - .metabolism-card { - display: flex; - flex-direction: column; - min-height: 280px; - } - - .metabolism-card .metabolism-content { - flex: 1; - display: flex; - flex-direction: column; - justify-content: space-between; - } - - .metabolism-card .info-grid { - grid-template-columns: 1fr; - gap: 12px; - } - - /* 体脂分析卡片网格优化 */ - .body-fat-card .info-grid { - grid-template-columns: repeat(2, 1fr); - gap: 15px; - } - - /* 理想三围卡片网格优化 */ - .measurements-card { - display: flex; - flex-direction: column; - min-height: 200px; - } - - .measurements-card .measurements-content { - flex: 1; - display: flex; - flex-direction: column; - justify-content: center; - } - - .measurements-card .info-grid { - grid-template-columns: 1fr; - gap: 15px; - } - - /* 健康建议卡片布局优化 */ - .advice-card { - padding: 30px; - } - - .advice-card .advice-content { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 25px; - margin-bottom: 25px; - } - - .advice-card .health-tips { - grid-column: 1 / -1; - display: grid; - grid-template-columns: repeat(2, 1fr); - gap: 15px; - list-style: none; - padding: 0; - } - - /* 表单区域优化 */ - .health-form { - display: grid; - gap: 25px; - } - - .form-group { - margin-bottom: 0; - } - - .submit-btn { - margin-top: 20px; - padding: 20px 30px; - font-size: 1.2rem; - } -} - -/* 手机端适配 (最高优先级) */ -@media (max-width: 767px) { - .container { - padding: 15px; - } - - .header { - margin-bottom: 20px; - padding: 15px 0; - } - - .title { - font-size: 2rem; - } - - .subtitle { - font-size: 1rem; - } - - .form-section { - padding: 20px; - border-radius: 16px; - } - - .form-input, - .form-select { - padding: 12px 16px; - font-size: 16px; /* 防止iOS缩放 */ - } - - .submit-btn { - padding: 16px 24px; - font-size: 1rem; - } - - .result-header { - flex-direction: column; - align-items: stretch; - gap: 15px; - } - - .result-title { - font-size: 1.6rem; - text-align: center; - } - - .reset-btn { - align-self: center; - padding: 12px 24px; - } - - .basic-info-card, - .bmi-card, - .weight-card, - .metabolism-card, - .body-fat-card, - .measurements-card, - .advice-card, - .disclaimer-card { - padding: 20px; - border-radius: 12px; - } - - .card-title { - font-size: 1.2rem; - } - - .info-grid { - grid-template-columns: 1fr; - gap: 12px; - } - - .bmi-value { - font-size: 2rem; - } - - .bmi-category { - font-size: 1.1rem; - } - - .health-tips li { - padding: 10px 12px; - font-size: 0.95rem; - } - - .error-content { - padding: 25px 20px; - } -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/身体健康分析/返回接口.json b/frontend/60sapi/实用功能/身体健康分析/返回接口.json deleted file mode 100644 index 455126d6..00000000 --- a/frontend/60sapi/实用功能/身体健康分析/返回接口.json +++ /dev/null @@ -1,93 +0,0 @@ -{ - "code": 200, - "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", - "data": { - "basic_info": { - "height": "176cm", - "height_desc": "身高", - "weight": "60kg", - "weight_desc": "体重", - "gender": "男性", - "gender_desc": "性别", - "age": "24岁", - "age_desc": "年龄" - }, - "bmi": { - "value": 19.37, - "value_desc": "BMI 值", - "category": "正常体重", - "category_desc": "BMI 分类", - "evaluation": "体重正常,保持良好", - "evaluation_desc": "BMI 评价", - "risk": "健康风险较低", - "risk_desc": "健康风险" - }, - "weight_assessment": { - "ideal_weight_range": "57.3-74.3kg", - "ideal_weight_range_desc": "理想体重范围", - "standard_weight": "71kg", - "standard_weight_desc": "标准体重", - "status": "体重正常", - "status_desc": "体重状态", - "adjustment": "保持当前体重", - "adjustment_desc": "调整建议" - }, - "metabolism": { - "bmr": "1601 卡路里/天", - "bmr_desc": "基础代谢率", - "tdee": "2561 卡路里/天", - "tdee_desc": "每日总消耗", - "recommended_calories": "2561 卡路里/天", - "recommended_calories_desc": "推荐卡路里摄入", - "weight_loss_calories": "2061 卡路里/天", - "weight_loss_calories_desc": "减重卡路里", - "weight_gain_calories": "2861 卡路里/天", - "weight_gain_calories_desc": "增重卡路里" - }, - "body_surface_area": { - "value": "1.74m²", - "value_desc": "体表面积", - "formula": "Du Bois 公式", - "formula_desc": "计算公式" - }, - "body_fat": { - "percentage": "12.6%", - "percentage_desc": "体脂率", - "category": "正常", - "category_desc": "体脂分类", - "fat_weight": "7.6kg", - "fat_weight_desc": "脂肪重量", - "lean_weight": "52.4kg", - "lean_weight_desc": "瘦体重" - }, - "health_advice": { - "daily_water_intake": "2000ml (约 8 杯水),运动时需额外补充 500-1000ml", - "daily_water_intake_desc": "每日饮水量", - "exercise_recommendation": "继续保持运动习惯,有氧运动和力量训练相结合效果更佳。年轻人可选择多样化的运动方式,建议每周运动 3-5 次", - "exercise_recommendation_desc": "运动建议", - "nutrition_advice": "保持均衡饮食,三大营养素合理搭配,定时定量进餐。年轻人新陈代谢较快,可适当增加能量摄入,男性可适当增加蛋白质摄入", - "nutrition_advice_desc": "营养建议", - "health_tips": [ - "保持充足睡眠,成年人建议每天 7-9 小时", - "定期体检有助于早期发现健康问题", - "保持良好心态,适当释放压力", - "年轻人要注意作息规律,合理安排工作与休息", - "长时间用眼后适当休息,保护视力", - "培养兴趣爱好,保持积极的生活态度", - "多饮水,成年人每天 1500-2000ml 为宜" - ], - "health_tips_desc": "健康提示" - }, - "ideal_measurements": { - "chest": "84cm", - "chest_desc": "胸围", - "waist": "74cm", - "waist_desc": "腰围", - "hip": "83cm", - "hip_desc": "臀围", - "note": "男性理想三围参考标准", - "note_desc": "说明" - }, - "disclaimer": "结果基于通用公式和统计数据,仅供参考,不能替代专业医疗建议。如有健康问题,请咨询医生。" - } -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/配色方案/background.css b/frontend/60sapi/实用功能/配色方案/background.css deleted file mode 100644 index 13feaa42..00000000 --- a/frontend/60sapi/实用功能/配色方案/background.css +++ /dev/null @@ -1,187 +0,0 @@ -/* 背景样式文件 - 单独管理所有背景相关样式 */ - -/* 主体背景 */ -body { - background: linear-gradient(135deg, #f0fff4 0%, #e6fffa 50%, #f0fff4 100%); - background-attachment: fixed; - position: relative; -} - -/* 背景装饰元素 */ -body::before { - content: ''; - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-image: - radial-gradient(circle at 20% 80%, rgba(104, 211, 145, 0.1) 0%, transparent 50%), - radial-gradient(circle at 80% 20%, rgba(72, 187, 120, 0.1) 0%, transparent 50%), - radial-gradient(circle at 40% 40%, rgba(56, 161, 105, 0.05) 0%, transparent 50%); - pointer-events: none; - z-index: -1; -} - -/* 容器背景 */ -.container { - background: rgba(255, 255, 255, 0.1); - backdrop-filter: blur(10px); - border-radius: 20px; - border: 1px solid rgba(255, 255, 255, 0.2); -} - -/* 输入区域背景 */ -.input-section { - background: rgba(255, 255, 255, 0.95); - backdrop-filter: blur(20px); - border: 1px solid rgba(104, 211, 145, 0.2); - position: relative; - overflow: hidden; -} - -.input-section::before { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - height: 3px; - background: linear-gradient(90deg, #48bb78, #68d391, #9ae6b4); -} - -/* 配色方案卡片背景 */ -.palette { - background: rgba(255, 255, 255, 0.95); - backdrop-filter: blur(15px); - border: 1px solid rgba(104, 211, 145, 0.15); - position: relative; - overflow: hidden; -} - -.palette::before { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - height: 2px; - background: linear-gradient(90deg, transparent, #68d391, transparent); - opacity: 0; - transition: opacity 0.3s ease; -} - -.palette:hover::before { - opacity: 1; -} - -/* 颜色信息背景 */ -.color-info { - background: rgba(255, 255, 255, 0.9); - backdrop-filter: blur(10px); - border: 1px solid rgba(104, 211, 145, 0.2); -} - -/* 颜色项背景 */ -.color-item { - background: rgba(255, 255, 255, 0.8); - backdrop-filter: blur(5px); - border: 1px solid rgba(104, 211, 145, 0.15); - position: relative; -} - -.color-item::after { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: linear-gradient(45deg, transparent 48%, rgba(104, 211, 145, 0.05) 50%, transparent 52%); - opacity: 0; - transition: opacity 0.3s ease; - pointer-events: none; -} - -.color-item:hover::after { - opacity: 1; -} - -/* 颜色详情背景 */ -.color-detail { - background: rgba(104, 211, 145, 0.08); - border: 1px solid rgba(104, 211, 145, 0.1); - position: relative; -} - -.color-detail::before { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, transparent 100%); - pointer-events: none; -} - -/* 按钮背景 */ -.generate-btn { - background: linear-gradient(135deg, #48bb78 0%, #68d391 50%, #9ae6b4 100%); - position: relative; - overflow: hidden; -} - -.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%; -} - -/* 加载动画背景 */ -.loading { - background: rgba(255, 255, 255, 0.9); - backdrop-filter: blur(10px); - border-radius: 12px; - border: 1px solid rgba(104, 211, 145, 0.2); -} - -/* 响应式背景调整 */ -@media (max-width: 768px) { - body { - background: linear-gradient(180deg, #f0fff4 0%, #e6fffa 100%); - } - - .container { - background: rgba(255, 255, 255, 0.05); - backdrop-filter: blur(5px); - } - - .input-section, - .palette, - .color-info { - backdrop-filter: blur(10px); - } -} - -@media (max-width: 480px) { - body::before { - background-image: - radial-gradient(circle at 50% 50%, rgba(104, 211, 145, 0.08) 0%, transparent 70%); - } - - .container { - background: transparent; - backdrop-filter: none; - border: none; - } -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/配色方案/index.html b/frontend/60sapi/实用功能/配色方案/index.html deleted file mode 100644 index 066b2764..00000000 --- a/frontend/60sapi/实用功能/配色方案/index.html +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - 配色方案生成器 - - - - -
    -
    -

    配色方案生成器

    -

    输入颜色值,获取专业的配色方案

    -
    - -
    -
    -
    - -
    - - -
    -
    - -
    - - -
    - - -
    - -
    - - - - -
    - -
    -
    -
    - -
    -

    基于色彩理论的专业配色方案生成

    -
    -
    - - - - \ No newline at end of file diff --git a/frontend/60sapi/实用功能/配色方案/script.js b/frontend/60sapi/实用功能/配色方案/script.js deleted file mode 100644 index 3bf8719f..00000000 --- a/frontend/60sapi/实用功能/配色方案/script.js +++ /dev/null @@ -1,315 +0,0 @@ -// 配色方案生成器 JavaScript -class ColorPaletteGenerator { - constructor() { - this.apiUrl = 'https://60s.api.shumengya.top/v2/color/palette'; - this.init(); - } - - init() { - this.bindEvents(); - this.loadDefaultPalette(); - } - - bindEvents() { - const colorInput = document.getElementById('colorInput'); - const colorPicker = document.getElementById('colorPicker'); - const generateBtn = document.getElementById('generateBtn'); - const formatSelect = document.getElementById('formatSelect'); - - // 颜色输入框事件 - colorInput.addEventListener('input', (e) => { - const color = e.target.value; - if (this.isValidColor(color)) { - colorPicker.value = color; - } - }); - - // 颜色选择器事件 - colorPicker.addEventListener('change', (e) => { - colorInput.value = e.target.value; - }); - - // 生成按钮事件 - generateBtn.addEventListener('click', () => { - this.generatePalette(); - }); - - // 回车键生成 - colorInput.addEventListener('keypress', (e) => { - if (e.key === 'Enter') { - this.generatePalette(); - } - }); - - // 格式选择事件 - formatSelect.addEventListener('change', () => { - const currentColor = colorInput.value; - if (currentColor && this.isValidColor(currentColor)) { - this.generatePalette(); - } - }); - } - - // 验证颜色格式 - isValidColor(color) { - const hexRegex = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/; - return hexRegex.test(color); - } - - // 显示加载状态 - showLoading() { - const loading = document.getElementById('loading'); - const colorInfo = document.getElementById('colorInfo'); - const palettesContainer = document.getElementById('palettesContainer'); - - loading.style.display = 'block'; - colorInfo.style.display = 'none'; - palettesContainer.innerHTML = ''; - } - - // 隐藏加载状态 - hideLoading() { - const loading = document.getElementById('loading'); - loading.style.display = 'none'; - } - - // 生成配色方案 - async generatePalette() { - const colorInput = document.getElementById('colorInput'); - const formatSelect = document.getElementById('formatSelect'); - const color = colorInput.value.trim(); - const format = formatSelect.value; - - if (!color) { - this.showError('请输入颜色值'); - return; - } - - if (!this.isValidColor(color)) { - this.showError('请输入有效的十六进制颜色值(如:#33AAFF)'); - return; - } - - this.showLoading(); - - try { - const url = new URL(this.apiUrl); - url.searchParams.append('color', color); - url.searchParams.append('encoding', format); - - const response = await fetch(url); - - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } - - const data = await response.json(); - - if (data.code === 200) { - this.displayResults(data.data); - } else { - throw new Error(data.message || '获取配色方案失败'); - } - } catch (error) { - console.error('Error:', error); - this.showError('获取配色方案失败,请检查网络连接或稍后重试'); - } finally { - this.hideLoading(); - } - } - - // 显示错误信息 - showError(message) { - const palettesContainer = document.getElementById('palettesContainer'); - palettesContainer.innerHTML = ` -
    -

    ❌ ${message}

    -
    - `; - } - - // 显示结果 - displayResults(data) { - this.displayColorInfo(data.input); - this.displayPalettes(data.palettes); - } - - // 显示颜色信息 - displayColorInfo(inputData) { - const colorInfo = document.getElementById('colorInfo'); - const colorPreview = document.getElementById('colorPreview'); - const colorDetails = document.getElementById('colorDetails'); - - colorPreview.style.backgroundColor = inputData.hex; - - colorDetails.innerHTML = ` -
    - HEX - ${inputData.hex} -
    -
    - RGB - rgb(${inputData.rgb.r}, ${inputData.rgb.g}, ${inputData.rgb.b}) -
    -
    - HSL - hsl(${inputData.hsl.h}°, ${inputData.hsl.s}%, ${inputData.hsl.l}%) -
    -
    - 色系 - ${inputData.name} -
    - `; - - colorInfo.style.display = 'block'; - } - - // 显示配色方案 - displayPalettes(palettes) { - const palettesContainer = document.getElementById('palettesContainer'); - - palettesContainer.innerHTML = palettes.map(palette => ` -
    -
    -

    ${palette.name}

    -

    ${palette.description}

    -
    -
    - ${palette.colors.map(color => ` -
    -
    -
    -
    ${color.name}
    -
    ${color.hex}
    -
    ${color.role} • ${color.theory}
    -
    - `).join('')} -
    -
    - `).join(''); - } - - // 加载默认配色方案 - async loadDefaultPalette() { - const colorInput = document.getElementById('colorInput'); - const defaultColor = colorInput.value; - - if (defaultColor && this.isValidColor(defaultColor)) { - await this.generatePalette(); - } - } -} - -// 复制到剪贴板功能 -function copyToClipboard(text) { - if (navigator.clipboard && window.isSecureContext) { - navigator.clipboard.writeText(text).then(() => { - showToast(`已复制 ${text} 到剪贴板`); - }).catch(err => { - console.error('复制失败:', err); - fallbackCopyTextToClipboard(text); - }); - } else { - fallbackCopyTextToClipboard(text); - } -} - -// 备用复制方法 -function fallbackCopyTextToClipboard(text) { - const textArea = document.createElement('textarea'); - textArea.value = text; - textArea.style.position = 'fixed'; - textArea.style.left = '-999999px'; - textArea.style.top = '-999999px'; - document.body.appendChild(textArea); - textArea.focus(); - textArea.select(); - - try { - document.execCommand('copy'); - showToast(`已复制 ${text} 到剪贴板`); - } catch (err) { - console.error('复制失败:', err); - showToast('复制失败,请手动复制'); - } - - document.body.removeChild(textArea); -} - -// 显示提示信息 -function showToast(message) { - // 移除已存在的toast - const existingToast = document.querySelector('.toast'); - if (existingToast) { - existingToast.remove(); - } - - const toast = document.createElement('div'); - toast.className = 'toast'; - toast.textContent = message; - toast.style.cssText = ` - position: fixed; - top: 20px; - right: 20px; - background: rgba(45, 90, 39, 0.95); - color: white; - padding: 12px 20px; - border-radius: 8px; - font-size: 14px; - font-weight: 500; - z-index: 10000; - box-shadow: 0 4px 12px rgba(45, 90, 39, 0.3); - transform: translateX(100%); - transition: transform 0.3s ease; - backdrop-filter: blur(10px); - `; - - document.body.appendChild(toast); - - // 动画显示 - setTimeout(() => { - toast.style.transform = 'translateX(0)'; - }, 100); - - // 3秒后隐藏 - setTimeout(() => { - toast.style.transform = 'translateX(100%)'; - setTimeout(() => { - if (toast.parentNode) { - toast.parentNode.removeChild(toast); - } - }, 300); - }, 3000); -} - -// 页面加载完成后初始化 -document.addEventListener('DOMContentLoaded', () => { - new ColorPaletteGenerator(); -}); - -// 添加移动端优化 -if ('ontouchstart' in window) { - // 移动端触摸优化 - document.addEventListener('touchstart', function() {}, {passive: true}); - - // 防止双击缩放 - let lastTouchEnd = 0; - document.addEventListener('touchend', function (event) { - const now = (new Date()).getTime(); - if (now - lastTouchEnd <= 300) { - event.preventDefault(); - } - lastTouchEnd = now; - }, false); -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/配色方案/styles.css b/frontend/60sapi/实用功能/配色方案/styles.css deleted file mode 100644 index 68225012..00000000 --- a/frontend/60sapi/实用功能/配色方案/styles.css +++ /dev/null @@ -1,422 +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: #2d3748; - min-height: 100vh; -} - -.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: #2d5a27; - margin-bottom: 10px; - font-weight: 700; -} - -.subtitle { - font-size: 1.1rem; - color: #68d391; - font-weight: 400; -} - -/* 主内容区域 */ -.main-content { - flex: 1; - display: flex; - flex-direction: column; - gap: 30px; -} - -/* 输入区域 */ -.input-section { - background: rgba(255, 255, 255, 0.9); - padding: 30px; - border-radius: 16px; - box-shadow: 0 4px 20px rgba(45, 90, 39, 0.1); - border: 1px solid rgba(104, 211, 145, 0.2); -} - -.color-input-group { - margin-bottom: 20px; -} - -.color-input-group label, -.format-select label { - display: block; - margin-bottom: 8px; - font-weight: 600; - color: #2d5a27; - font-size: 0.95rem; -} - -.input-wrapper { - display: flex; - gap: 10px; - align-items: center; -} - -#colorInput { - flex: 1; - padding: 12px 16px; - border: 2px solid #e2e8f0; - border-radius: 8px; - font-size: 1rem; - transition: all 0.3s ease; - background: white; -} - -#colorInput:focus { - outline: none; - border-color: #68d391; - box-shadow: 0 0 0 3px rgba(104, 211, 145, 0.1); -} - -#colorPicker { - width: 50px; - height: 44px; - border: 2px solid #e2e8f0; - border-radius: 8px; - cursor: pointer; - background: none; -} - -.format-select { - margin-bottom: 25px; -} - -#formatSelect { - width: 100%; - padding: 12px 16px; - border: 2px solid #e2e8f0; - border-radius: 8px; - font-size: 1rem; - background: white; - cursor: pointer; - transition: all 0.3s ease; -} - -#formatSelect:focus { - outline: none; - border-color: #68d391; - box-shadow: 0 0 0 3px rgba(104, 211, 145, 0.1); -} - -.generate-btn { - width: 100%; - padding: 14px 24px; - background: linear-gradient(135deg, #48bb78, #68d391); - color: white; - border: none; - border-radius: 8px; - font-size: 1.1rem; - font-weight: 600; - cursor: pointer; - transition: all 0.3s ease; - box-shadow: 0 4px 12px rgba(72, 187, 120, 0.3); -} - -.generate-btn:hover { - background: linear-gradient(135deg, #38a169, #48bb78); - transform: translateY(-2px); - box-shadow: 0 6px 20px rgba(72, 187, 120, 0.4); -} - -.generate-btn:active { - transform: translateY(0); -} - -/* 结果区域 */ -.result-section { - min-height: 200px; -} - -.loading { - text-align: center; - padding: 40px; -} - -.spinner { - width: 40px; - height: 40px; - border: 4px solid #e2e8f0; - border-top: 4px solid #68d391; - 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: #68d391; - font-weight: 500; -} - -/* 颜色信息 */ -.color-info { - background: rgba(255, 255, 255, 0.9); - padding: 25px; - border-radius: 12px; - margin-bottom: 25px; - box-shadow: 0 2px 10px rgba(45, 90, 39, 0.1); - border: 1px solid rgba(104, 211, 145, 0.2); -} - -.color-info h3 { - color: #2d5a27; - margin-bottom: 15px; - font-size: 1.3rem; -} - -.color-preview { - width: 100%; - height: 60px; - border-radius: 8px; - margin-bottom: 15px; - border: 2px solid rgba(104, 211, 145, 0.3); -} - -.color-details { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); - gap: 15px; -} - -.color-detail { - text-align: center; - padding: 10px; - background: rgba(104, 211, 145, 0.1); - border-radius: 6px; -} - -.color-detail strong { - display: block; - color: #2d5a27; - font-size: 0.9rem; - margin-bottom: 5px; -} - -.color-detail span { - color: #4a5568; - font-size: 0.95rem; -} - -/* 配色方案容器 */ -.palettes-container { - display: grid; - gap: 25px; -} - -.palette { - background: rgba(255, 255, 255, 0.9); - border-radius: 12px; - padding: 25px; - box-shadow: 0 4px 15px rgba(45, 90, 39, 0.1); - border: 1px solid rgba(104, 211, 145, 0.2); - transition: transform 0.3s ease, box-shadow 0.3s ease; -} - -.palette:hover { - transform: translateY(-3px); - box-shadow: 0 8px 25px rgba(45, 90, 39, 0.15); -} - -.palette-header { - margin-bottom: 20px; -} - -.palette-name { - font-size: 1.4rem; - color: #2d5a27; - margin-bottom: 8px; - font-weight: 600; -} - -.palette-description { - color: #68d391; - font-size: 0.95rem; - line-height: 1.5; -} - -.colors-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); - gap: 15px; -} - -.color-item { - background: white; - border-radius: 8px; - padding: 15px; - border: 1px solid rgba(104, 211, 145, 0.2); - transition: all 0.3s ease; -} - -.color-item:hover { - transform: translateY(-2px); - box-shadow: 0 4px 12px rgba(45, 90, 39, 0.1); -} - -.color-swatch { - width: 100%; - height: 50px; - border-radius: 6px; - margin-bottom: 10px; - border: 1px solid rgba(0, 0, 0, 0.1); - cursor: pointer; - position: relative; - overflow: hidden; -} - -.color-swatch::after { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: linear-gradient(45deg, transparent 45%, rgba(255,255,255,0.1) 50%, transparent 55%); - opacity: 0; - transition: opacity 0.3s ease; -} - -.color-swatch:hover::after { - opacity: 1; -} - -.color-name { - font-weight: 600; - color: #2d5a27; - margin-bottom: 5px; - font-size: 0.9rem; -} - -.color-hex { - font-family: 'Courier New', monospace; - color: #4a5568; - font-size: 0.85rem; - margin-bottom: 3px; -} - -.color-role { - font-size: 0.8rem; - color: #68d391; - font-style: italic; -} - -/* 底部 */ -.footer { - text-align: center; - padding: 30px 0; - margin-top: 40px; - color: #68d391; - font-size: 0.9rem; -} - -/* 平板端适配 */ -@media (max-width: 1024px) { - .container { - padding: 15px; - } - - .header h1 { - font-size: 2.2rem; - } - - .colors-grid { - grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); - } -} - -/* 手机端适配 */ -@media (max-width: 768px) { - .container { - padding: 10px; - } - - .header { - margin-bottom: 25px; - padding: 20px 0; - } - - .header h1 { - font-size: 1.8rem; - } - - .subtitle { - font-size: 1rem; - } - - .input-section { - padding: 20px; - } - - .input-wrapper { - flex-direction: column; - align-items: stretch; - } - - #colorPicker { - width: 100%; - height: 44px; - } - - .colors-grid { - grid-template-columns: 1fr; - } - - .color-details { - grid-template-columns: repeat(2, 1fr); - } - - .palette { - padding: 20px; - } - - .palette-name { - font-size: 1.2rem; - } -} - -@media (max-width: 480px) { - .header h1 { - font-size: 1.6rem; - } - - .input-section { - padding: 15px; - } - - .palette { - padding: 15px; - } - - .color-details { - grid-template-columns: 1fr; - } -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/配色方案/返回接口.json b/frontend/60sapi/实用功能/配色方案/返回接口.json deleted file mode 100644 index 6f353332..00000000 --- a/frontend/60sapi/实用功能/配色方案/返回接口.json +++ /dev/null @@ -1,273 +0,0 @@ -{ - "code": 200, - "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", - "data": { - "input": { - "hex": "#DE4F99", - "rgb": { - "r": 222, - "g": 79, - "b": 153 - }, - "hsl": { - "h": 329, - "s": 68, - "l": 59 - }, - "name": "红色系" - }, - "palettes": [ - { - "name": "单色配色", - "description": "基于同一色相,通过调整明度和饱和度创建的和谐配色方案,适合营造统一、专业的视觉效果", - "colors": [ - { - "hex": "#DE4F99", - "name": "主色", - "role": "primary", - "theory": "基础色相" - }, - { - "hex": "#7C184C", - "name": "深色变体", - "role": "dark", - "theory": "降低明度" - }, - { - "hex": "#EEA5CB", - "name": "浅色变体", - "role": "light", - "theory": "提高明度" - }, - { - "hex": "#C96498", - "name": "柔和变体", - "role": "muted", - "theory": "降低饱和度" - }, - { - "hex": "#ED4099", - "name": "鲜艳变体", - "role": "vibrant", - "theory": "提高饱和度" - } - ] - }, - { - "name": "互补配色", - "description": "使用色轮上相对的颜色,创造强烈对比和视觉冲击力,适用于需要突出重点的设计", - "colors": [ - { - "hex": "#DE4F99", - "name": "主色", - "role": "primary", - "theory": "基础色相" - }, - { - "hex": "#4FDE94", - "name": "互补色", - "role": "complementary", - "theory": "色轮对面 +180°" - }, - { - "hex": "#F2BAD7", - "name": "主色浅调", - "role": "primary-light", - "theory": "主色提高明度" - }, - { - "hex": "#BAF2D5", - "name": "互补色浅调", - "role": "complementary-light", - "theory": "互补色提高明度" - } - ] - }, - { - "name": "邻近配色", - "description": "使用色轮上相邻的颜色,创造自然和谐的渐变效果,常见于自然景观中", - "colors": [ - { - "hex": "#DB4FDE", - "name": "邻近色1", - "role": "analogous-1", - "theory": "色相 -30°" - }, - { - "hex": "#DE4F99", - "name": "主色", - "role": "primary", - "theory": "基础色相" - }, - { - "hex": "#DE4F52", - "name": "邻近色2", - "role": "analogous-2", - "theory": "色相 +30°" - }, - { - "hex": "#DE944F", - "name": "邻近色3", - "role": "analogous-3", - "theory": "色相 +60°" - } - ] - }, - { - "name": "三角配色", - "description": "在色轮上形成等边三角形的三种颜色,提供丰富对比的同时保持和谐平衡", - "colors": [ - { - "hex": "#DE4F99", - "name": "主色", - "role": "primary", - "theory": "基础色相" - }, - { - "hex": "#99DE4F", - "name": "三角色1", - "role": "triadic-1", - "theory": "色相 +120°" - }, - { - "hex": "#4F99DE", - "name": "三角色2", - "role": "triadic-2", - "theory": "色相 +240°" - } - ] - }, - { - "name": "分裂互补配色", - "description": "使用互补色两侧的颜色,比纯互补配色更柔和,同时保持强烈的视觉对比", - "colors": [ - { - "hex": "#DE4F99", - "name": "主色", - "role": "primary", - "theory": "基础色相" - }, - { - "hex": "#52DE4F", - "name": "分裂互补色1", - "role": "split-comp-1", - "theory": "互补色 -30°" - }, - { - "hex": "#4FDEDB", - "name": "分裂互补色2", - "role": "split-comp-2", - "theory": "互补色 +30°" - } - ] - }, - { - "name": "四边形配色", - "description": "在色轮上形成正方形的四种颜色,提供最丰富的颜色变化,适合复杂的设计项目", - "colors": [ - { - "hex": "#DE4F99", - "name": "主色", - "role": "primary", - "theory": "基础色相" - }, - { - "hex": "#DEDB4F", - "name": "四边形色1", - "role": "square-1", - "theory": "色相 +90°" - }, - { - "hex": "#4FDE94", - "name": "四边形色2", - "role": "square-2", - "theory": "色相 +180°" - }, - { - "hex": "#4F52DE", - "name": "四边形色3", - "role": "square-3", - "theory": "色相 +270°" - } - ] - }, - { - "name": "Web 设计配色", - "description": "专为 Web 界面设计优化的配色方案,考虑了可访问性和用户体验", - "colors": [ - { - "hex": "#DE4F99", - "name": "品牌主色", - "role": "brand-primary", - "theory": "品牌识别色" - }, - { - "hex": "#982F65", - "name": "按钮悬停", - "role": "hover-state", - "theory": "主色加深变体" - }, - { - "hex": "#F6E9F0", - "name": "背景浅色", - "role": "background", - "theory": "高明度低饱和度" - }, - { - "hex": "#1BDE7A", - "name": "强调色", - "role": "accent", - "theory": "互补色系强调" - }, - { - "hex": "#6B7280", - "name": "文本辅助", - "role": "text-secondary", - "theory": "中性灰色文本" - } - ] - }, - { - "name": "暖色调配色", - "description": "基于暖色系的配色方案,营造温暖、活力和友好的氛围,适合餐饮、儿童产品等", - "colors": [ - { - "hex": "#DE4F99", - "name": "主暖色", - "role": "warm-primary", - "theory": "暖色系基调" - }, - { - "hex": "#DE4FC8", - "name": "暖色变体1", - "role": "warm-variant-1", - "theory": "暖色范围内调整" - }, - { - "hex": "#DE4F5E", - "name": "暖色变体2", - "role": "warm-variant-2", - "theory": "暖色范围内调整" - }, - { - "hex": "#EEA5CB", - "name": "暖色浅调", - "role": "warm-tint", - "theory": "提高明度的暖色" - } - ] - } - ], - "metadata": { - "color_theory": "基于色彩理论生成的专业配色方案", - "total_palettes": 8, - "applications": [ - "Web 设计", - "UI/UX", - "品牌设计", - "室内设计", - "服装搭配" - ] - } - } -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/链接OG信息/css/background.css b/frontend/60sapi/实用功能/链接OG信息/css/background.css deleted file mode 100755 index 27d9e571..00000000 --- a/frontend/60sapi/实用功能/链接OG信息/css/background.css +++ /dev/null @@ -1,232 +0,0 @@ -/* 高维度背景特效样式 - 神秘高级风格 */ - -/* 背景容器 */ -.background-container { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: 1; - overflow: hidden; - pointer-events: none; - background: radial-gradient(ellipse at center, - rgba(15, 0, 30, 0.95) 0%, - rgba(5, 0, 15, 0.98) 50%, - rgba(0, 0, 0, 1) 100%); -} - -/* 几何网格层 */ -.geometric-grid { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-image: - linear-gradient(rgba(138, 43, 226, 0.1) 1px, transparent 1px), - linear-gradient(90deg, rgba(138, 43, 226, 0.1) 1px, transparent 1px), - linear-gradient(rgba(75, 0, 130, 0.05) 1px, transparent 1px), - linear-gradient(90deg, rgba(75, 0, 130, 0.05) 1px, transparent 1px); - background-size: 100px 100px, 100px 100px, 20px 20px, 20px 20px; - animation: gridPulse 8s ease-in-out infinite; -} - -@keyframes gridPulse { - 0%, 100% { opacity: 0.3; transform: scale(1); } - 50% { opacity: 0.6; transform: scale(1.02); } -} - -/* 神经网络效果 */ -.neural-network { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: - radial-gradient(circle at 20% 30%, rgba(138, 43, 226, 0.15) 2px, transparent 2px), - radial-gradient(circle at 80% 20%, rgba(75, 0, 130, 0.12) 1px, transparent 1px), - radial-gradient(circle at 40% 70%, rgba(147, 0, 211, 0.1) 1.5px, transparent 1.5px), - radial-gradient(circle at 90% 80%, rgba(138, 43, 226, 0.08) 1px, transparent 1px), - radial-gradient(circle at 10% 90%, rgba(75, 0, 130, 0.1) 2px, transparent 2px); - background-size: 200px 200px, 150px 150px, 300px 300px, 180px 180px, 250px 250px; - animation: neuralFlow 15s linear infinite; -} - -@keyframes neuralFlow { - 0% { transform: translate(0, 0) rotate(0deg); } - 25% { transform: translate(-10px, -5px) rotate(90deg); } - 50% { transform: translate(-5px, -10px) rotate(180deg); } - 75% { transform: translate(5px, -5px) rotate(270deg); } - 100% { transform: translate(0, 0) rotate(360deg); } -} - -/* 粒子系统 */ -.particle-system { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-image: - radial-gradient(circle, rgba(138, 43, 226, 0.4) 1px, transparent 1px), - radial-gradient(circle, rgba(75, 0, 130, 0.3) 0.5px, transparent 0.5px), - radial-gradient(circle, rgba(147, 0, 211, 0.2) 0.8px, transparent 0.8px); - background-size: 80px 80px, 120px 120px, 160px 160px; - background-position: 0 0, 40px 40px, 80px 80px; - animation: particleFloat 20s ease-in-out infinite; -} - -@keyframes particleFloat { - 0%, 100% { transform: translateY(0px) translateX(0px); } - 25% { transform: translateY(-20px) translateX(10px); } - 50% { transform: translateY(-10px) translateX(-15px); } - 75% { transform: translateY(-30px) translateX(5px); } -} - -/* 扫描线效果 */ -.scan-lines { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: repeating-linear-gradient( - 0deg, - transparent 0px, - transparent 2px, - rgba(138, 43, 226, 0.03) 2px, - rgba(138, 43, 226, 0.03) 4px - ); - animation: scanMove 3s linear infinite; -} - -@keyframes scanMove { - 0% { transform: translateY(-100%); } - 100% { transform: translateY(100%); } -} - -/* 全息投影效果 */ -.holographic-overlay { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: - linear-gradient(45deg, - transparent 30%, - rgba(138, 43, 226, 0.05) 50%, - transparent 70%), - linear-gradient(-45deg, - transparent 30%, - rgba(75, 0, 130, 0.03) 50%, - transparent 70%); - background-size: 200px 200px, 150px 150px; - animation: holographicShift 12s ease-in-out infinite; -} - -@keyframes holographicShift { - 0%, 100% { - background-position: 0% 0%, 100% 100%; - opacity: 0.7; - } - 50% { - background-position: 100% 100%, 0% 0%; - opacity: 1; - } -} - -/* 数据流效果 */ -.data-stream { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: - linear-gradient(90deg, - transparent 0%, - rgba(138, 43, 226, 0.1) 50%, - transparent 100%); - background-size: 300px 100%; - animation: dataFlow 8s linear infinite; -} - -@keyframes dataFlow { - 0% { transform: translateX(-100%); } - 100% { transform: translateX(100%); } -} - -/* 量子波动效果 */ -.quantum-waves { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: - radial-gradient(ellipse 200px 100px at 50% 0%, - rgba(138, 43, 226, 0.1) 0%, - transparent 50%), - radial-gradient(ellipse 300px 150px at 50% 100%, - rgba(75, 0, 130, 0.08) 0%, - transparent 50%); - animation: quantumPulse 10s ease-in-out infinite; -} - -@keyframes quantumPulse { - 0%, 100% { - transform: scale(1) rotate(0deg); - opacity: 0.5; - } - 50% { - transform: scale(1.1) rotate(180deg); - opacity: 0.8; - } -} - -/* 响应式优化 */ -@media (max-width: 768px) { - .geometric-grid { - background-size: 50px 50px, 50px 50px, 10px 10px, 10px 10px; - } - - .neural-network { - background-size: 100px 100px, 75px 75px, 150px 150px, 90px 90px, 125px 125px; - } - - .particle-system { - background-size: 40px 40px, 60px 60px, 80px 80px; - } -} - -/* 减少动画偏好 */ -@media (prefers-reduced-motion: reduce) { - .geometric-grid, - .neural-network, - .particle-system, - .scan-lines, - .holographic-overlay, - .data-stream, - .quantum-waves { - animation: none; - } -} - -/* 高对比度模式 */ -@media (prefers-contrast: high) { - .background-container { - background: radial-gradient(ellipse at center, - rgba(25, 0, 50, 0.95) 0%, - rgba(10, 0, 25, 0.98) 50%, - rgba(0, 0, 0, 1) 100%); - } - - .geometric-grid { - background-image: - linear-gradient(rgba(200, 100, 255, 0.2) 1px, transparent 1px), - linear-gradient(90deg, rgba(200, 100, 255, 0.2) 1px, transparent 1px); - } -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/链接OG信息/css/style.css b/frontend/60sapi/实用功能/链接OG信息/css/style.css deleted file mode 100755 index e36e7c0d..00000000 --- a/frontend/60sapi/实用功能/链接OG信息/css/style.css +++ /dev/null @@ -1,1159 +0,0 @@ -/* 全局样式重置 */ -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -/* 根变量定义 */ -:root { - /* 神秘色彩系统 */ - --primary-dark: #0a0a0a; - --secondary-dark: #1a1a1a; - --accent-dark: #2a2a2a; - --border-dark: #333333; - - /* 神秘绿色系统 */ - --neon-green: #00ff88; - --dark-green: #004d2a; - --light-green: #66ffaa; - --glow-green: rgba(0, 255, 136, 0.3); - - /* 高级紫色系统 */ - --neon-purple: #8a2be2; - --dark-purple: #4a0e4e; - --light-purple: #b347d9; - --glow-purple: rgba(138, 43, 226, 0.3); - - /* 文字颜色 */ - --text-primary: #ffffff; - --text-secondary: #cccccc; - --text-muted: #888888; - --text-accent: var(--neon-green); - - /* 间距系统 */ - --spacing-xs: 0.5rem; - --spacing-sm: 1rem; - --spacing-md: 1.5rem; - --spacing-lg: 2rem; - --spacing-xl: 3rem; - - /* 字体系统 */ - --font-primary: 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; - --font-mono: 'SF Mono', 'Monaco', 'Cascadia Code', 'Roboto Mono', monospace; - - /* 阴影系统 */ - --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.3); - --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.4); - --shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.5); - --shadow-glow: 0 0 20px var(--glow-green); - --shadow-purple-glow: 0 0 20px var(--glow-purple); - - /* 边框半径 */ - --radius-sm: 4px; - --radius-md: 8px; - --radius-lg: 12px; - --radius-xl: 16px; - - /* 过渡效果 */ - --transition-fast: 0.2s ease; - --transition-normal: 0.3s ease; - --transition-slow: 0.5s ease; -} - -/* 基础样式 */ -body { - font-family: var(--font-primary); - background: var(--primary-dark); - color: var(--text-primary); - line-height: 1.6; - overflow-x: hidden; - min-height: 100vh; - position: relative; -} - -/* 主容器 */ -.main-container { - position: relative; - z-index: 10; - min-height: 100vh; - display: flex; - flex-direction: column; - max-width: 1400px; - margin: 0 auto; - padding: var(--spacing-lg); -} - -/* 头部样式 */ -.header { - margin-bottom: var(--spacing-xl); - position: relative; -} - -.header-content { - display: flex; - justify-content: space-between; - align-items: center; - padding: var(--spacing-lg); - background: linear-gradient(135deg, var(--secondary-dark), var(--accent-dark)); - border: 1px solid var(--border-dark); - border-radius: var(--radius-xl); - backdrop-filter: blur(10px); - position: relative; - overflow: hidden; -} - -.header-content::before { - content: ''; - position: absolute; - top: 0; - left: -100%; - width: 100%; - height: 100%; - background: linear-gradient(90deg, transparent, var(--glow-green), transparent); - animation: scanLine 3s infinite; -} - -@keyframes scanLine { - 0% { left: -100%; } - 100% { left: 100%; } -} - -.logo-section { - display: flex; - align-items: center; - gap: var(--spacing-md); -} - -.logo-icon { - font-size: 2.5rem; - color: var(--neon-green); - filter: drop-shadow(0 0 10px var(--glow-green)); - animation: pulse 2s infinite; -} - -@keyframes pulse { - 0%, 100% { transform: scale(1); } - 50% { transform: scale(1.1); } -} - -.title { - font-size: 2.5rem; - font-weight: 700; - background: linear-gradient(45deg, var(--neon-green), var(--light-green)); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; - text-shadow: 0 0 20px var(--glow-green); -} - -.subtitle { - font-size: 1rem; - color: var(--text-secondary); - font-family: var(--font-mono); - opacity: 0.8; -} - -.status-indicator { - display: flex; - align-items: center; - gap: var(--spacing-xs); - padding: var(--spacing-sm) var(--spacing-md); - background: rgba(0, 255, 136, 0.1); - border: 1px solid var(--neon-green); - border-radius: var(--radius-lg); - backdrop-filter: blur(5px); -} - -.pulse-dot { - width: 8px; - height: 8px; - background: var(--neon-green); - border-radius: 50%; - animation: pulseGlow 1.5s infinite; -} - -@keyframes pulseGlow { - 0%, 100% { - opacity: 1; - box-shadow: 0 0 5px var(--glow-green); - } - 50% { - opacity: 0.5; - box-shadow: 0 0 15px var(--glow-green); - } -} - -.status-text { - font-size: 0.9rem; - color: var(--neon-green); - font-family: var(--font-mono); -} - -/* 查询区域 */ -.query-section { - margin-bottom: var(--spacing-xl); -} - -.input-container { - display: flex; - gap: var(--spacing-md); - align-items: stretch; -} - -.input-wrapper { - flex: 1; - position: relative; - background: var(--secondary-dark); - border-radius: var(--radius-lg); - overflow: hidden; -} - -.input-icon { - position: absolute; - left: var(--spacing-md); - top: 50%; - transform: translateY(-50%); - color: var(--text-muted); - font-size: 1.2rem; - z-index: 2; - transition: var(--transition-normal); -} - -.url-input { - width: 100%; - padding: var(--spacing-md) var(--spacing-md) var(--spacing-md) 3.5rem; - background: transparent; - border: 2px solid var(--border-dark); - border-radius: var(--radius-lg); - color: var(--text-primary); - font-size: 1.1rem; - font-family: var(--font-mono); - transition: var(--transition-normal); - position: relative; - z-index: 1; -} - -.url-input:focus { - outline: none; - border-color: var(--neon-green); - box-shadow: var(--shadow-glow); -} - -.url-input:focus + .input-border { - opacity: 1; - animation: borderGlow 2s infinite; -} - -.url-input:focus ~ .input-icon { - color: var(--neon-green); -} - -.input-border { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - border: 2px solid var(--neon-green); - border-radius: var(--radius-lg); - opacity: 0; - pointer-events: none; - transition: var(--transition-normal); -} - -@keyframes borderGlow { - 0%, 100% { box-shadow: 0 0 5px var(--glow-green); } - 50% { box-shadow: 0 0 20px var(--glow-green); } -} - -.analyze-btn { - position: relative; - padding: var(--spacing-md) var(--spacing-xl); - background: linear-gradient(135deg, var(--dark-green), var(--neon-green)); - border: none; - border-radius: var(--radius-lg); - color: var(--primary-dark); - font-size: 1.1rem; - font-weight: 600; - cursor: pointer; - overflow: hidden; - transition: var(--transition-normal); - min-width: 150px; -} - -.analyze-btn:hover { - transform: translateY(-2px); - box-shadow: var(--shadow-glow); -} - -.analyze-btn:active { - transform: translateY(0); -} - -.btn-text { - position: relative; - z-index: 2; -} - -.btn-effects { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - pointer-events: none; -} - -.ripple { - position: absolute; - top: 50%; - left: 50%; - width: 0; - height: 0; - background: rgba(255, 255, 255, 0.3); - border-radius: 50%; - transform: translate(-50%, -50%); - transition: var(--transition-fast); -} - -.analyze-btn:active .ripple { - width: 200px; - height: 200px; -} - -/* 加载状态 */ -.loading-container { - display: flex; - justify-content: center; - align-items: center; - padding: var(--spacing-xl); - margin: var(--spacing-xl) 0; -} - -.loading-content { - text-align: center; - display: flex; - flex-direction: column; - align-items: center; - gap: var(--spacing-lg); -} - -.scanner { - position: relative; - width: 200px; - height: 200px; - border: 2px solid var(--border-dark); - border-radius: var(--radius-lg); - background: var(--secondary-dark); - overflow: hidden; -} - -.scanner-line { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 2px; - background: linear-gradient(90deg, transparent, var(--neon-green), transparent); - animation: scannerMove 2s infinite; -} - -@keyframes scannerMove { - 0% { top: 0; } - 100% { top: calc(100% - 2px); } -} - -.scanner-grid { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - display: grid; - grid-template-columns: repeat(4, 1fr); - gap: 1px; -} - -.grid-line { - background: var(--border-dark); - opacity: 0.3; - animation: gridPulse 1.5s infinite; -} - -.grid-line:nth-child(1) { animation-delay: 0s; } -.grid-line:nth-child(2) { animation-delay: 0.2s; } -.grid-line:nth-child(3) { animation-delay: 0.4s; } -.grid-line:nth-child(4) { animation-delay: 0.6s; } - -@keyframes gridPulse { - 0%, 100% { opacity: 0.3; } - 50% { opacity: 0.8; background: var(--glow-green); } -} - -.loading-text { - display: flex; - flex-direction: column; - gap: var(--spacing-xs); -} - -.loading-title { - font-size: 1.5rem; - font-weight: 600; - color: var(--neon-green); -} - -.loading-subtitle { - font-size: 1rem; - color: var(--text-secondary); - font-family: var(--font-mono); -} - -/* 结果展示区域 */ -.results-section { - margin-bottom: var(--spacing-xl); -} - -.results-header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: var(--spacing-lg); - padding: var(--spacing-md); - background: var(--secondary-dark); - border-radius: var(--radius-lg); - border: 1px solid var(--border-dark); -} - -.results-title { - display: flex; - align-items: center; - gap: var(--spacing-sm); - font-size: 1.5rem; - font-weight: 600; - color: var(--neon-green); -} - -.results-actions { - display: flex; - gap: var(--spacing-sm); -} - -.action-btn { - display: flex; - align-items: center; - gap: var(--spacing-xs); - padding: var(--spacing-sm) var(--spacing-md); - background: var(--accent-dark); - border: 1px solid var(--border-dark); - border-radius: var(--radius-md); - color: var(--text-secondary); - font-size: 0.9rem; - cursor: pointer; - transition: var(--transition-normal); -} - -.action-btn:hover { - background: var(--border-dark); - color: var(--text-primary); - border-color: var(--neon-green); -} - -/* OG卡片 */ -.og-card { - background: var(--secondary-dark); - border: 1px solid var(--border-dark); - border-radius: var(--radius-xl); - overflow: hidden; - box-shadow: var(--shadow-lg); -} - -.info-section { - padding: var(--spacing-lg); - border-bottom: 1px solid var(--border-dark); -} - -.info-section:last-child { - border-bottom: none; -} - -.section-header { - display: flex; - align-items: center; - gap: var(--spacing-sm); - margin-bottom: var(--spacing-md); - font-size: 1.2rem; - font-weight: 600; - color: var(--text-accent); -} - -.info-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); - gap: var(--spacing-md); -} - -.info-item { - display: flex; - flex-direction: column; - gap: var(--spacing-xs); -} - -.info-item label { - font-size: 0.9rem; - color: var(--text-muted); - font-family: var(--font-mono); - text-transform: uppercase; - letter-spacing: 0.5px; -} - -.info-value { - padding: var(--spacing-sm); - background: var(--accent-dark); - border: 1px solid var(--border-dark); - border-radius: var(--radius-md); - color: var(--text-primary); - font-family: var(--font-mono); - word-break: break-all; - transition: var(--transition-normal); -} - -.info-value:hover { - border-color: var(--neon-green); - box-shadow: 0 0 10px var(--glow-green); -} - -.url-value { - color: var(--light-green); - cursor: pointer; -} - -.url-value:hover { - color: var(--neon-green); -} - -/* 媒体预览 */ -.media-preview { - margin-bottom: var(--spacing-md); - border-radius: var(--radius-lg); - overflow: hidden; - background: var(--accent-dark); - border: 1px solid var(--border-dark); - min-height: 200px; - display: flex; - align-items: center; - justify-content: center; -} - -.media-preview img { - max-width: 100%; - max-height: 300px; - object-fit: contain; - border-radius: var(--radius-md); -} - -.no-media { - display: flex; - flex-direction: column; - align-items: center; - gap: var(--spacing-sm); - color: var(--text-muted); - font-size: 1.1rem; -} - -.no-media i { - font-size: 2rem; - opacity: 0.5; -} - -.media-details { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); - gap: var(--spacing-md); -} - -/* 错误状态 */ -.error-container { - display: flex; - justify-content: center; - align-items: center; - padding: var(--spacing-xl); - margin: var(--spacing-xl) 0; -} - -.error-content { - text-align: center; - padding: var(--spacing-xl); - background: var(--secondary-dark); - border: 2px solid #ff4444; - border-radius: var(--radius-xl); - max-width: 500px; - box-shadow: 0 0 20px rgba(255, 68, 68, 0.3); -} - -.error-icon { - font-size: 3rem; - color: #ff4444; - margin-bottom: var(--spacing-md); - animation: shake 0.5s infinite; -} - -@keyframes shake { - 0%, 100% { transform: translateX(0); } - 25% { transform: translateX(-5px); } - 75% { transform: translateX(5px); } -} - -.error-title { - font-size: 1.5rem; - font-weight: 600; - color: #ff4444; - margin-bottom: var(--spacing-sm); -} - -.error-message { - color: var(--text-secondary); - margin-bottom: var(--spacing-lg); - font-family: var(--font-mono); -} - -.retry-btn { - display: inline-flex; - align-items: center; - gap: var(--spacing-xs); - padding: var(--spacing-sm) var(--spacing-lg); - background: #ff4444; - border: none; - border-radius: var(--radius-md); - color: white; - font-weight: 600; - cursor: pointer; - transition: var(--transition-normal); -} - -.retry-btn:hover { - background: #ff6666; - transform: translateY(-2px); -} - -/* Tip 消息样式 */ -.tip-container { - position: fixed; - bottom: 2rem; - left: 2rem; - z-index: 999; - opacity: 0; - transform: translateY(20px); - transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94); - pointer-events: none; -} - -.tip-container.active { - opacity: 1; - transform: translateY(0); - pointer-events: auto; -} - -.tip-content { - background: linear-gradient(135deg, - rgba(138, 43, 226, 0.1) 0%, - rgba(75, 0, 130, 0.1) 100%); - border: 1px solid rgba(138, 43, 226, 0.3); - border-radius: var(--radius-lg); - padding: var(--spacing-md); - backdrop-filter: blur(10px); - box-shadow: - 0 8px 32px rgba(0, 0, 0, 0.3), - 0 0 20px rgba(138, 43, 226, 0.1), - inset 0 1px 0 rgba(255, 255, 255, 0.1); - display: flex; - align-items: center; - gap: var(--spacing-sm); - min-width: 300px; - max-width: 400px; -} - -.tip-icon { - font-size: 1.2rem; - color: var(--neon-purple); - flex-shrink: 0; -} - -.tip-text { - color: var(--text-secondary); - font-size: 0.9rem; - line-height: 1.4; -} - -/* 提示消息 */ -.toast-container { - position: fixed; - top: var(--spacing-lg); - right: var(--spacing-lg); - z-index: 1000; - transform: translateX(100%); - transition: var(--transition-normal); -} - -.toast-container.show { - transform: translateX(0); -} - -.toast-content { - display: flex; - align-items: center; - gap: var(--spacing-sm); - padding: var(--spacing-md) var(--spacing-lg); - background: var(--secondary-dark); - border: 1px solid var(--neon-green); - border-radius: var(--radius-lg); - color: var(--text-primary); - box-shadow: var(--shadow-glow); - backdrop-filter: blur(10px); -} - -.toast-icon { - font-size: 1.2rem; - color: var(--neon-green); -} - -.toast-message { - font-family: var(--font-mono); - font-size: 0.9rem; -} - -/* 页脚 */ -.footer { - margin-top: auto; - padding: var(--spacing-lg); - border-top: 1px solid var(--border-dark); - background: var(--secondary-dark); - border-radius: var(--radius-lg); -} - -.footer-content { - display: flex; - justify-content: space-between; - align-items: center; - text-align: center; -} - -.footer-text { - display: flex; - align-items: center; - gap: var(--spacing-xs); - color: var(--text-muted); - font-size: 0.9rem; - font-family: var(--font-mono); -} - -.footer-links { - display: flex; - align-items: center; - gap: var(--spacing-sm); - font-size: 0.8rem; - color: var(--text-muted); -} - -.footer-link { - cursor: pointer; - transition: var(--transition-normal); -} - -.footer-link:hover { - color: var(--neon-green); -} - -.footer-divider { - opacity: 0.5; -} - -/* 响应式设计 */ - -/* 平板设备 */ -@media (max-width: 1024px) { - .main-container { - padding: var(--spacing-md); - } - - .header-content { - flex-direction: column; - gap: var(--spacing-md); - text-align: center; - } - - .title { - font-size: 2rem; - } - - .input-container { - flex-direction: column; - } - - .analyze-btn { - width: 100%; - } - - .info-grid { - grid-template-columns: 1fr; - } - - .results-header { - flex-direction: column; - gap: var(--spacing-md); - } - - .footer-content { - flex-direction: column; - gap: var(--spacing-sm); - } -} - -/* 交互动画增强 */ -.input-glow { - position: absolute; - top: -2px; - left: -2px; - right: -2px; - bottom: -2px; - background: linear-gradient(45deg, - var(--neon-green), - var(--light-green), - var(--neon-purple)); - border-radius: inherit; - z-index: -1; - opacity: 0; - animation: glowPulse 2s ease-in-out; -} - -@keyframes glowPulse { - 0%, 100% { opacity: 0; transform: scale(1); } - 50% { opacity: 0.6; transform: scale(1.02); } -} - -.input-container.shake { - animation: inputShake 0.6s ease-in-out; -} - -@keyframes inputShake { - 0%, 100% { transform: translateX(0); } - 10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); } - 20%, 40%, 60%, 80% { transform: translateX(5px); } -} - -.analyze-btn.flash, -.action-btn.flash { - animation: buttonFlash 0.3s ease-in-out; -} - -@keyframes buttonFlash { - 0%, 100% { background: linear-gradient(135deg, var(--dark-green), var(--neon-green)); } - 50% { background: var(--neon-purple); box-shadow: 0 0 20px var(--glow-purple); } -} - -.og-card.animate-in { - animation: cardSlideIn 0.6s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards; -} - -@keyframes cardSlideIn { - 0% { - opacity: 0; - transform: translateY(30px) scale(0.95); - } - 100% { - opacity: 1; - transform: translateY(0) scale(1); - } -} - -.header.animate-in { - animation: headerFadeIn 1s ease-out forwards; -} - -@keyframes headerFadeIn { - 0% { - opacity: 0; - transform: translateY(-20px); - } - 100% { - opacity: 1; - transform: translateY(0); - } -} - -.query-section.animate-in { - animation: sectionSlideUp 0.8s ease-out 0.2s forwards; - opacity: 0; -} - -@keyframes sectionSlideUp { - 0% { - opacity: 0; - transform: translateY(40px); - } - 100% { - opacity: 1; - transform: translateY(0); - } -} - -@keyframes fadeInUp { - 0% { - opacity: 0; - transform: translateY(20px); - } - 100% { - opacity: 1; - transform: translateY(0); - } -} - -@keyframes fadeOutDown { - 0% { - opacity: 1; - transform: translateY(0); - } - 100% { - opacity: 0; - transform: translateY(20px); - } -} - -/* 高级悬浮效果 */ -.og-card:hover { - transform: translateY(-5px) scale(1.02); - box-shadow: - 0 10px 30px var(--glow-purple), - 0 0 20px rgba(138, 43, 226, 0.1), - inset 0 1px 0 rgba(255, 255, 255, 0.1); -} - -.analyze-btn:hover:not(:disabled) { - transform: translateY(-3px); - box-shadow: - 0 8px 25px var(--glow-green), - 0 0 15px rgba(0, 255, 136, 0.2); -} - -.action-btn:hover:not(:disabled) { - transform: translateY(-1px); - box-shadow: 0 5px 15px var(--glow-purple); -} - -/* 图片加载动画 */ -.media-preview img { - transition: all 0.3s ease; -} - -.media-preview img:hover { - transform: scale(1.05); - box-shadow: 0 8px 25px var(--glow-green); -} - -.image-placeholder { - background: linear-gradient(135deg, - var(--glow-green) 0%, - var(--glow-purple) 100%); - border: 2px dashed rgba(138, 43, 226, 0.3); - display: none; - align-items: center; - justify-content: center; - min-height: 200px; - border-radius: var(--radius-lg); - color: var(--text-secondary); - font-size: 0.9rem; -} - -/* 手机设备 */ -@media (max-width: 768px) { - .main-container { - padding: var(--spacing-sm); - } - - .header-content { - padding: var(--spacing-md); - } - - .title { - font-size: 1.8rem; - } - - .subtitle { - font-size: 0.9rem; - } - - .logo-icon { - font-size: 2rem; - } - - .url-input { - font-size: 16px; /* 防止iOS缩放 */ - padding: var(--spacing-sm) var(--spacing-sm) var(--spacing-sm) 3rem; - } - - .input-icon { - left: var(--spacing-sm); - font-size: 1rem; - } - - .analyze-btn { - padding: var(--spacing-sm) var(--spacing-md); - font-size: 1rem; - } - - .scanner { - width: 150px; - height: 150px; - } - - .loading-title { - font-size: 1.3rem; - } - - .loading-subtitle { - font-size: 0.9rem; - } - - .results-title { - font-size: 1.3rem; - } - - .action-btn { - font-size: 0.8rem; - padding: var(--spacing-xs) var(--spacing-sm); - } - - .info-section { - padding: var(--spacing-md); - } - - .section-header { - font-size: 1.1rem; - } - - .media-details { - grid-template-columns: 1fr; - } - - .toast-container { - top: var(--spacing-sm); - right: var(--spacing-sm); - left: var(--spacing-sm); - transform: translateY(-100%); - } - - .toast-container.show { - transform: translateY(0); - } - - .footer-text { - font-size: 0.8rem; - } - - .footer-links { - font-size: 0.7rem; - } - - /* 移动设备上禁用部分悬浮效果 */ - .og-card:hover { - transform: none; - } - - .media-preview img:hover { - transform: none; - } -} - -/* 小屏手机设备 */ -@media (max-width: 480px) { - .main-container { - padding: var(--spacing-xs); - } - - .title { - font-size: 1.5rem; - } - - .logo-section { - flex-direction: column; - gap: var(--spacing-sm); - } - - .scanner { - width: 120px; - height: 120px; - } - - .error-content { - padding: var(--spacing-md); - } - - .error-icon { - font-size: 2.5rem; - } - - .error-title { - font-size: 1.3rem; - } -} - -/* 高分辨率屏幕优化 */ -@media (min-width: 1440px) { - .main-container { - max-width: 1600px; - } - - .title { - font-size: 3rem; - } - - .url-input { - font-size: 1.2rem; - } - - .analyze-btn { - font-size: 1.2rem; - padding: var(--spacing-lg) var(--spacing-xl); - } -} - -/* 深色模式优化 */ -@media (prefers-color-scheme: dark) { - :root { - --primary-dark: #000000; - --secondary-dark: #111111; - --accent-dark: #222222; - } -} - -/* 减少动画偏好 */ -@media (prefers-reduced-motion: reduce) { - * { - animation-duration: 0.01ms !important; - animation-iteration-count: 1 !important; - transition-duration: 0.01ms !important; - } -} - -/* 打印样式 */ -@media print { - .background-container, - .header, - .query-section, - .loading-container, - .error-container, - .toast-container, - .footer { - display: none; - } - - .results-section { - margin: 0; - padding: 0; - } - - .og-card { - border: 1px solid #000; - box-shadow: none; - } -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/链接OG信息/index.html b/frontend/60sapi/实用功能/链接OG信息/index.html deleted file mode 100755 index 2f603665..00000000 --- a/frontend/60sapi/实用功能/链接OG信息/index.html +++ /dev/null @@ -1,227 +0,0 @@ - - - - - - 链接OG信息查询 - 神秘解析器 - - - - - - - -
    -
    -
    -
    -
    - - -
    - -
    -
    -
    - -

    OG 解析器

    - 链接元数据神秘解析 -
    -
    -
    - 系统就绪 -
    -
    -
    - - -
    -
    -
    - - -
    -
    - -
    -
    - - - - - - - - - -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    - -
    - - - - \ No newline at end of file diff --git a/frontend/60sapi/实用功能/链接OG信息/js/script.js b/frontend/60sapi/实用功能/链接OG信息/js/script.js deleted file mode 100755 index f7059a9c..00000000 --- a/frontend/60sapi/实用功能/链接OG信息/js/script.js +++ /dev/null @@ -1,617 +0,0 @@ -// 链接OG信息查询 - JavaScript功能代码 -// 神秘高级风格的交互体验 - -class OGAnalyzer { - constructor() { - this.apiUrl = 'https://60s.api.shumengya.top/v2/og'; - this.isAnalyzing = false; - this.currentUrl = ''; - this.animationFrameId = null; - - this.init(); - } - - init() { - this.bindEvents(); - this.createBackgroundEffects(); - this.initializeAnimations(); - this.showWelcomeMessage(); - this.initPageAnimations(); - } - - // 初始化页面动画 - initPageAnimations() { - // 延迟添加动画类,确保CSS已加载 - setTimeout(() => { - const header = document.querySelector('.header'); - const querySection = document.querySelector('.query-section'); - - if (header) header.classList.add('animate-in'); - if (querySection) querySection.classList.add('animate-in'); - }, 100); - } - - bindEvents() { - const urlInput = document.getElementById('url-input'); - const analyzeBtn = document.getElementById('analyze-btn'); - const copyBtn = document.getElementById('copy-btn'); - const clearBtn = document.getElementById('clear-btn'); - - // 输入框事件 - urlInput.addEventListener('input', (e) => this.handleUrlInput(e)); - urlInput.addEventListener('keypress', (e) => { - if (e.key === 'Enter' && !this.isAnalyzing) { - this.analyzeUrl(); - } - }); - urlInput.addEventListener('focus', () => this.handleInputFocus()); - urlInput.addEventListener('blur', () => this.handleInputBlur()); - - // 按钮事件 - analyzeBtn.addEventListener('click', () => this.analyzeUrl()); - copyBtn.addEventListener('click', () => this.copyResults()); - clearBtn.addEventListener('click', () => this.clearResults()); - - // 键盘快捷键 - document.addEventListener('keydown', (e) => this.handleKeyboard(e)); - } - - handleUrlInput(e) { - const url = e.target.value.trim(); - const analyzeBtn = document.getElementById('analyze-btn'); - - if (this.isValidUrl(url)) { - analyzeBtn.classList.add('ready'); - e.target.classList.remove('error'); - } else { - analyzeBtn.classList.remove('ready'); - if (url.length > 0) { - e.target.classList.add('error'); - } else { - e.target.classList.remove('error'); - } - } - } - - handleInputFocus() { - const inputContainer = document.querySelector('.input-container'); - inputContainer.classList.add('focused'); - this.createInputGlow(); - } - - handleInputBlur() { - const inputContainer = document.querySelector('.input-container'); - inputContainer.classList.remove('focused'); - } - - handleKeyboard(e) { - // Ctrl/Cmd + Enter 快速分析 - if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') { - e.preventDefault(); - if (!this.isAnalyzing) { - this.analyzeUrl(); - } - } - - // Escape 清除结果 - if (e.key === 'Escape') { - this.clearResults(); - } - } - - isValidUrl(string) { - try { - const url = new URL(string); - return url.protocol === 'http:' || url.protocol === 'https:'; - } catch (_) { - return false; - } - } - - async analyzeUrl() { - const urlInput = document.getElementById('url-input'); - const url = urlInput.value.trim(); - - if (!this.isValidUrl(url)) { - this.showError('请输入有效的URL地址'); - this.shakeInput(); - return; - } - - if (this.isAnalyzing) { - return; - } - - this.currentUrl = url; - this.isAnalyzing = true; - this.startTime = Date.now(); // 记录开始时间 - this.showLoading(); - this.hideError(); - this.hideResults(); - - try { - const response = await fetch(`${this.apiUrl}?url=${encodeURIComponent(url)}`); - - if (!response.ok) { - throw new Error(`HTTP ${response.status}: ${response.statusText}`); - } - - const data = await response.json(); - - if (data.code === 200 && data.data) { - await this.displayResults(data.data); - this.showSuccessMessage('分析完成!'); - - // 添加按钮闪烁效果 - const analyzeBtn = document.getElementById('analyze-btn'); - analyzeBtn.classList.add('flash'); - setTimeout(() => { - analyzeBtn.classList.remove('flash'); - }, 300); - } else { - throw new Error(data.message || '获取OG信息失败'); - } - } catch (error) { - console.error('分析失败:', error); - this.showError(`分析失败: ${error.message}`); - } finally { - this.isAnalyzing = false; - this.hideLoading(); - } - } - - showLoading() { - const loadingElement = document.getElementById('loading'); - const analyzeBtn = document.getElementById('analyze-btn'); - - loadingElement.classList.add('active'); - analyzeBtn.disabled = true; - analyzeBtn.textContent = '分析中...'; - - this.startScannerAnimation(); - } - - hideLoading() { - const loadingElement = document.getElementById('loading'); - const analyzeBtn = document.getElementById('analyze-btn'); - - loadingElement.classList.remove('active'); - analyzeBtn.disabled = false; - analyzeBtn.textContent = '开始分析'; - - this.stopScannerAnimation(); - } - - async displayResults(data) { - const resultsElement = document.getElementById('results'); - const ogCard = document.getElementById('og-card'); - - // 检查是否有有效数据 - 放宽检查条件,只要有任何非空字段就显示 - const hasValidData = Object.values(data).some(value => { - if (value === null || value === undefined) return false; - if (typeof value === 'string') return value.trim() !== ''; - return true; // 其他类型的值都认为是有效的 - }); - - if (!hasValidData) { - this.showError('该链接暂无可获取的OG信息,请检查链接是否正确或稍后重试'); - return; - } - - // 基础信息 - 只显示有数据的字段 - this.updateElementWithVisibility('og-title', data.title, '标题'); - this.updateElementWithVisibility('og-description', data.description, '描述'); - this.updateElement('og-url', data.url || this.currentUrl); // URL始终显示 - this.updateElementWithVisibility('og-site-name', data.site_name, '网站名称'); - this.updateElement('og-type', data.type || 'website'); // 类型始终显示 - - // 媒体信息 - this.updateImageElementWithVisibility('og-image', data.image); - this.updateElementWithVisibility('og-image-alt', data.image_alt, '图片描述'); - - // 技术信息 - this.updateElementWithVisibility('og-locale', data.locale, '语言'); - this.updateElementWithVisibility('og-updated-time', this.formatDate(data.updated_time), '更新时间'); - this.updateElement('response-time', `${Date.now() - this.startTime}ms`); // 响应时间始终显示 - - // 显示结果 - resultsElement.style.display = 'block'; - resultsElement.classList.add('active'); - - // 添加动画效果 - await this.animateResults(); - - // 启用操作按钮 - document.getElementById('copy-btn').disabled = false; - document.getElementById('clear-btn').disabled = false; - } - - updateElement(id, content) { - const element = document.getElementById(id); - if (element) { - element.textContent = content; - } - } - - updateElementWithVisibility(id, content, fieldName) { - const element = document.getElementById(id); - if (!element) return; - - const parentItem = element.closest('.info-item'); - if (!parentItem) return; - - if (content && content.trim() !== '') { - element.textContent = content; - parentItem.style.display = 'block'; - } else { - parentItem.style.display = 'none'; - } - } - - updateImageElement(id, imageSrc) { - const element = document.getElementById(id); - if (element && imageSrc) { - element.src = imageSrc; - element.style.display = 'block'; - element.onerror = () => { - element.style.display = 'none'; - const placeholder = element.nextElementSibling; - if (placeholder && placeholder.classList.contains('image-placeholder')) { - placeholder.style.display = 'flex'; - } - }; - } else if (element) { - element.style.display = 'none'; - const placeholder = element.nextElementSibling; - if (placeholder && placeholder.classList.contains('image-placeholder')) { - placeholder.style.display = 'flex'; - } - } - } - - updateImageElementWithVisibility(id, imageSrc) { - const element = document.getElementById(id); - const mediaSection = document.querySelector('.media-info'); - const mediaPreview = document.getElementById('media-preview'); - - if (imageSrc && imageSrc.trim() !== '') { - element.textContent = imageSrc; - if (mediaSection) mediaSection.style.display = 'block'; - - if (mediaPreview) { - mediaPreview.innerHTML = ` - OG Image - - `; - } - } else { - if (mediaSection) mediaSection.style.display = 'none'; - } - } - - formatDate(timestamp) { - if (!timestamp) return '未知'; - try { - const date = new Date(timestamp); - return date.toLocaleString('zh-CN'); - } catch (e) { - return '格式错误'; - } - } - - async animateResults() { - const cards = document.querySelectorAll('.info-card'); - - for (let i = 0; i < cards.length; i++) { - setTimeout(() => { - cards[i].classList.add('animate-in'); - }, i * 100); - } - - // 等待动画完成 - await new Promise(resolve => setTimeout(resolve, cards.length * 100 + 300)); - } - - showError(message) { - const errorElement = document.getElementById('error-message'); - const errorText = errorElement.querySelector('.error-text'); - const inputContainer = document.querySelector('.input-container'); - - errorText.textContent = message; - errorElement.classList.add('active'); - - // 添加震动效果 - if (inputContainer) { - inputContainer.classList.add('shake'); - setTimeout(() => { - inputContainer.classList.remove('shake'); - }, 600); - } - - // 自动隐藏错误信息 - setTimeout(() => { - this.hideError(); - }, 5000); - } - - hideError() { - const errorElement = document.getElementById('error-message'); - errorElement.classList.remove('active'); - } - - hideResults() { - const resultsElement = document.getElementById('results'); - resultsElement.style.display = 'none'; - resultsElement.classList.remove('active'); - - // 重置动画状态 - const cards = document.querySelectorAll('.info-card'); - cards.forEach(card => card.classList.remove('animate-in')); - } - - showSuccessMessage(message) { - const tipElement = document.getElementById('tip-message'); - const tipText = tipElement.querySelector('.tip-text'); - - tipText.textContent = message; - tipElement.classList.add('active'); - - setTimeout(() => { - tipElement.classList.remove('active'); - }, 3000); - } - - shakeInput() { - const inputContainer = document.querySelector('.input-container'); - inputContainer.classList.add('shake'); - - setTimeout(() => { - inputContainer.classList.remove('shake'); - }, 600); - } - - copyResults() { - const ogData = { - title: document.getElementById('og-title').textContent, - description: document.getElementById('og-description').textContent, - url: document.getElementById('og-url').textContent, - site_name: document.getElementById('og-site-name').textContent, - type: document.getElementById('og-type').textContent, - image: document.getElementById('og-image').src, - locale: document.getElementById('og-locale').textContent - }; - - const jsonString = JSON.stringify(ogData, null, 2); - - navigator.clipboard.writeText(jsonString).then(() => { - this.showSuccessMessage('结果已复制到剪贴板!'); - this.flashCopyButton(); - }).catch(err => { - console.error('复制失败:', err); - this.showError('复制失败,请手动选择内容'); - }); - } - - flashCopyButton() { - const copyBtn = document.getElementById('copy-btn'); - copyBtn.classList.add('flash'); - - setTimeout(() => { - copyBtn.classList.remove('flash'); - }, 300); - } - - clearResults() { - const urlInput = document.getElementById('url-input'); - const resultsElement = document.getElementById('results'); - const errorElement = document.getElementById('error-message'); - - urlInput.value = ''; - urlInput.classList.remove('error'); - resultsElement.style.display = 'none'; - resultsElement.classList.remove('active'); - errorElement.classList.remove('active'); - - document.getElementById('analyze-btn').classList.remove('ready'); - document.getElementById('copy-btn').disabled = true; - document.getElementById('clear-btn').disabled = true; - - this.currentUrl = ''; - - // 重置所有字段的显示状态 - const infoItems = document.querySelectorAll('.info-item'); - infoItems.forEach(item => item.style.display = 'block'); - - const mediaSection = document.querySelector('.media-info'); - if (mediaSection) mediaSection.style.display = 'block'; - - // 重置动画状态 - const cards = document.querySelectorAll('.info-card'); - cards.forEach(card => card.classList.remove('animate-in')); - - this.showSuccessMessage('已清除所有内容'); - } - - createBackgroundEffects() { - const container = document.querySelector('.background-container'); - - // 创建各种背景效果层 - const effects = [ - 'geometric-grid', - 'neural-network', - 'particle-system', - 'scan-lines', - 'holographic-overlay', - 'data-stream', - 'quantum-waves' - ]; - - effects.forEach(effectClass => { - const layer = document.createElement('div'); - layer.className = effectClass; - container.appendChild(layer); - }); - } - - createInputGlow() { - const inputContainer = document.querySelector('.input-container'); - - // 创建光晕效果 - const glow = document.createElement('div'); - glow.className = 'input-glow'; - inputContainer.appendChild(glow); - - setTimeout(() => { - if (glow.parentNode) { - glow.remove(); - } - }, 2000); - } - - startScannerAnimation() { - const scanner = document.querySelector('.scanner'); - if (scanner) { - scanner.classList.add('active'); - } - } - - stopScannerAnimation() { - const scanner = document.querySelector('.scanner'); - if (scanner) { - scanner.classList.remove('active'); - } - } - - initializeAnimations() { - // 初始化页面动画 - const header = document.querySelector('.header'); - const querySection = document.querySelector('.query-section'); - - setTimeout(() => { - header.classList.add('animate-in'); - }, 100); - - setTimeout(() => { - querySection.classList.add('animate-in'); - }, 300); - } - - showWelcomeMessage() { - const tips = [ - '支持分析网页的标题、描述、图片等元信息', - '可以预览社交媒体分享时的显示效果', - '检测网页的SEO优化情况', - '分析Open Graph协议标签' - ]; - - setTimeout(() => { - this.showSuccessMessage('欢迎使用链接OG信息分析器!'); - }, 1000); - - // 显示提示信息 - this.showTips(tips); - } - - // 显示提示信息 - showTips(tips) { - const tipElement = document.getElementById('tip-message'); - const tipText = tipElement.querySelector('.tip-text'); - - let currentTip = 0; - - const showNextTip = () => { - tipText.textContent = tips[currentTip]; - tipElement.classList.add('active'); - tipElement.style.animation = 'fadeInUp 0.5s ease-out'; - - setTimeout(() => { - tipElement.style.animation = 'fadeOutDown 0.5s ease-in'; - setTimeout(() => { - tipElement.classList.remove('active'); - currentTip = (currentTip + 1) % tips.length; - }, 500); - }, 3000); - }; - - // 首次显示 - setTimeout(showNextTip, 2000); - - // 每8秒显示一次 - setInterval(showNextTip, 8000); - } -} - -// 工具函数 -function debounce(func, wait) { - let timeout; - return function executedFunction(...args) { - const later = () => { - clearTimeout(timeout); - func(...args); - }; - clearTimeout(timeout); - timeout = setTimeout(later, wait); - }; -} - -function 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); - } - } -} - -// 页面加载完成后初始化 -document.addEventListener('DOMContentLoaded', () => { - // 检查必要的DOM元素 - const requiredElements = [ - 'url-input', 'analyze-btn', 'copy-btn', 'clear-btn', - 'loading', 'results', 'error-message', 'tip-message' - ]; - - const missingElements = requiredElements.filter(id => !document.getElementById(id)); - - if (missingElements.length > 0) { - console.error('缺少必要的DOM元素:', missingElements); - return; - } - - // 初始化应用 - window.ogAnalyzer = new OGAnalyzer(); - - // 添加全局错误处理 - window.addEventListener('error', (e) => { - console.error('全局错误:', e.error); - if (window.ogAnalyzer) { - window.ogAnalyzer.showError('发生未知错误,请刷新页面重试'); - } - }); - - // 添加网络状态监听 - window.addEventListener('online', () => { - if (window.ogAnalyzer) { - window.ogAnalyzer.showSuccessMessage('网络连接已恢复'); - } - }); - - window.addEventListener('offline', () => { - if (window.ogAnalyzer) { - window.ogAnalyzer.showError('网络连接已断开'); - } - }); -}); - -// 导出给其他模块使用 -if (typeof module !== 'undefined' && module.exports) { - module.exports = { OGAnalyzer, debounce, throttle }; -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/链接OG信息/接口集合.json b/frontend/60sapi/实用功能/链接OG信息/接口集合.json deleted file mode 100755 index 547b2771..00000000 --- a/frontend/60sapi/实用功能/链接OG信息/接口集合.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "https://60s.api.shumengya.top" -] diff --git a/frontend/60sapi/实用功能/链接OG信息/返回接口.json b/frontend/60sapi/实用功能/链接OG信息/返回接口.json deleted file mode 100755 index de8516ab..00000000 --- a/frontend/60sapi/实用功能/链接OG信息/返回接口.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "code": 200, - "message": "success", - "data": { - "url": "https://example.com", - "title": "示例网站标题", - "description": "这是一个示例网站的描述信息,用于展示OG标签解析功能。", - "image": "https://example.com/og-image.jpg", - "site_name": "示例网站", - "type": "website", - "locale": "zh_CN", - "author": "网站作者", - "keywords": "示例,网站,OG标签,元数据", - "favicon": "https://example.com/favicon.ico", - "canonical_url": "https://example.com", - "robots": "index,follow", - "viewport": "width=device-width, initial-scale=1.0", - "charset": "UTF-8", - "language": "zh-CN", - "published_time": "2024-01-01T00:00:00Z", - "modified_time": "2024-01-15T12:30:00Z", - "section": "技术", - "tags": ["前端", "元数据", "SEO"], - "twitter": { - "card": "summary_large_image", - "site": "@example", - "creator": "@author", - "title": "Twitter标题", - "description": "Twitter描述", - "image": "https://example.com/twitter-image.jpg" - }, - "facebook": { - "app_id": "123456789", - "admins": "987654321" - }, - "structured_data": { - "@context": "https://schema.org", - "@type": "WebPage", - "name": "示例网页", - "description": "示例网页描述", - "url": "https://example.com" - }, - "meta_tags": { - "generator": "WordPress 6.0", - "theme-color": "#000000", - "msapplication-TileColor": "#ffffff", - "apple-mobile-web-app-capable": "yes", - "apple-mobile-web-app-status-bar-style": "default" - }, - "performance": { - "load_time": 1.25, - "page_size": "2.3MB", - "requests_count": 45 - }, - "seo_score": { - "overall": 85, - "title_score": 90, - "description_score": 80, - "image_score": 85, - "structure_score": 88 - } - }, - "timestamp": "2024-01-15T12:30:45Z", - "request_id": "req_123456789", - "processing_time": 0.85 -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/随机密码生成器/css/background.css b/frontend/60sapi/实用功能/随机密码生成器/css/background.css deleted file mode 100644 index 4108e5b7..00000000 --- a/frontend/60sapi/实用功能/随机密码生成器/css/background.css +++ /dev/null @@ -1,252 +0,0 @@ -/* 背景样式文件 */ - -/* 主背景渐变 */ -body { - background: linear-gradient(135deg, #e8f5e8 0%, #f0f9f0 25%, #f8fdf8 50%, #e8f5e8 75%, #f0f9f0 100%); - 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(76, 175, 80, 0.1) 0%, transparent 50%), - radial-gradient(circle at 80% 20%, rgba(45, 90, 61, 0.08) 0%, transparent 50%), - radial-gradient(circle at 40% 40%, rgba(76, 175, 80, 0.05) 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(45, 90, 61, 0.2), transparent), - radial-gradient(1px 1px at 90px 40px, rgba(76, 175, 80, 0.4), transparent), - radial-gradient(1px 1px at 130px 80px, rgba(45, 90, 61, 0.3), transparent), - radial-gradient(2px 2px at 160px 30px, rgba(76, 175, 80, 0.2), transparent); - background-repeat: repeat; - background-size: 200px 100px; - animation: floatDots 20s linear infinite; - pointer-events: none; - z-index: -1; - opacity: 0.6; -} - -/* 圆点浮动动画 */ -@keyframes floatDots { - 0% { - transform: translateY(0px) translateX(0px); - } - 33% { - transform: translateY(-10px) translateX(5px); - } - 66% { - transform: translateY(5px) translateX(-5px); - } - 100% { - transform: translateY(0px) translateX(0px); - } -} - -/* 网格背景(可选,默认隐藏) */ -.grid-background { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-image: - linear-gradient(rgba(76, 175, 80, 0.03) 1px, transparent 1px), - linear-gradient(90deg, rgba(76, 175, 80, 0.03) 1px, transparent 1px); - background-size: 50px 50px; - pointer-events: none; - z-index: -3; - opacity: 0; - transition: opacity 0.3s ease; -} - -.grid-background.active { - opacity: 1; -} - -/* 响应式背景调整 */ -@media (max-width: 768px) { - body::after { - background-size: 150px 75px; - animation-duration: 25s; - } - - body::before { - background-image: - radial-gradient(circle at 30% 70%, rgba(76, 175, 80, 0.08) 0%, transparent 50%), - radial-gradient(circle at 70% 30%, rgba(45, 90, 61, 0.06) 0%, transparent 50%); - } -} - -@media (max-width: 480px) { - body { - animation-duration: 20s; - } - - body::after { - background-size: 100px 50px; - opacity: 0.4; - } -} - -/* 高对比度模式下的背景调整 */ -@media (prefers-contrast: high) { - body { - background: #f8fdf8; - animation: none; - } - - body::before, - body::after { - display: none; - } -} - -/* 减少动画模式下的背景调整 */ -@media (prefers-reduced-motion: reduce) { - body { - animation: none; - background: linear-gradient(135deg, #e8f5e8 0%, #f0f9f0 50%, #f8fdf8 100%); - } - - body::after { - animation: none; - } - - @keyframes gradientShift { - 0%, 100% { - background-position: 0% 50%; - } - } - - @keyframes floatDots { - 0%, 100% { - transform: translateY(0px) translateX(0px); - } - } -} - -/* 深色模式支持 */ -@media (prefers-color-scheme: dark) { - body { - background: linear-gradient(135deg, #1a2e1a 0%, #2d4a2d 25%, #1f3a1f 50%, #1a2e1a 75%, #2d4a2d 100%); - } - - body::before { - background-image: - radial-gradient(circle at 20% 80%, rgba(76, 175, 80, 0.15) 0%, transparent 50%), - radial-gradient(circle at 80% 20%, rgba(144, 238, 144, 0.1) 0%, transparent 50%), - radial-gradient(circle at 40% 40%, rgba(76, 175, 80, 0.08) 0%, transparent 50%); - } - - body::after { - background-image: - radial-gradient(2px 2px at 20px 30px, rgba(144, 238, 144, 0.4), transparent), - radial-gradient(2px 2px at 40px 70px, rgba(76, 175, 80, 0.3), transparent), - radial-gradient(1px 1px at 90px 40px, rgba(144, 238, 144, 0.5), transparent), - radial-gradient(1px 1px at 130px 80px, rgba(76, 175, 80, 0.4), transparent), - radial-gradient(2px 2px at 160px 30px, rgba(144, 238, 144, 0.3), transparent); - } -} - -/* 打印样式 */ -@media print { - body { - background: white !important; - animation: none !important; - } - - body::before, - body::after { - display: none !important; - } -} - -/* 特殊效果:鼠标悬停时的背景变化 */ -@media (hover: hover) { - .container:hover { - position: relative; - } - - .container:hover::before { - content: ''; - position: absolute; - top: -20px; - left: -20px; - right: -20px; - bottom: -20px; - background: radial-gradient(circle at var(--mouse-x, 50%) var(--mouse-y, 50%), rgba(76, 175, 80, 0.05) 0%, transparent 50%); - border-radius: 30px; - pointer-events: none; - z-index: -1; - transition: opacity 0.3s ease; - } -} - -/* 季节性主题变化(可通过JavaScript控制) */ -.theme-spring body { - background: linear-gradient(135deg, #e8f5e8 0%, #f0f9f0 25%, #e1f5e1 50%, #f8fdf8 75%, #e8f5e8 100%); -} - -.theme-summer body { - background: linear-gradient(135deg, #f0f9f0 0%, #e8f5e8 25%, #f8fdf8 50%, #e1f5e1 75%, #f0f9f0 100%); -} - -.theme-autumn body { - background: linear-gradient(135deg, #f5f0e8 0%, #f9f5f0 25%, #fdf8f0 50%, #f5f0e8 75%, #f9f5f0 100%); -} - -.theme-winter body { - background: linear-gradient(135deg, #f0f5f8 0%, #f5f9fc 25%, #f8fbfd 50%, #f0f5f8 75%, #f5f9fc 100%); -} - -/* 性能优化:GPU加速 */ -body, -body::before, -body::after { - will-change: transform; - transform: translateZ(0); -} - -/* 无障碍支持:为屏幕阅读器隐藏装饰元素 */ -body::before, -body::after { - speak: none; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/随机密码生成器/css/style.css b/frontend/60sapi/实用功能/随机密码生成器/css/style.css deleted file mode 100644 index 2793ae86..00000000 --- a/frontend/60sapi/实用功能/随机密码生成器/css/style.css +++ /dev/null @@ -1,647 +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: #2d5a3d; - min-height: 100vh; - overflow-x: hidden; -} - -/* 容器布局 */ -.container { - max-width: 800px; - margin: 0 auto; - padding: 20px; - min-height: 100vh; - display: flex; - flex-direction: column; -} - -/* 头部样式 */ -.header { - text-align: center; - margin-bottom: 40px; - padding: 30px 20px; - background: linear-gradient(135deg, #e8f5e8 0%, #f0f9f0 100%); - border-radius: 20px; - box-shadow: 0 4px 20px rgba(45, 90, 61, 0.1); -} - -.header h1 { - font-size: 2.5rem; - font-weight: 700; - color: #2d5a3d; - margin-bottom: 10px; - text-shadow: 0 2px 4px rgba(45, 90, 61, 0.1); -} - -.subtitle { - font-size: 1.1rem; - color: #5a8a6b; - font-weight: 400; -} - -/* 主内容区域 */ -.main-content { - flex: 1; - display: flex; - flex-direction: column; - gap: 30px; -} - -/* 表单容器 */ -.form-container { - background: #ffffff; - border-radius: 16px; - padding: 30px; - box-shadow: 0 8px 32px rgba(45, 90, 61, 0.1); - border: 1px solid #e8f5e8; -} - -.password-form { - display: flex; - flex-direction: column; - gap: 25px; -} - -/* 表单组样式 */ -.form-group { - display: flex; - flex-direction: column; - gap: 12px; -} - -.form-group label { - font-weight: 600; - color: #2d5a3d; - font-size: 1rem; -} - -.section-title { - font-size: 1.1rem; - color: #2d5a3d; - font-weight: 600; - margin-bottom: 8px; -} - -/* 长度控制 */ -.length-control { - display: flex; - align-items: center; - gap: 15px; - padding: 15px; - background: #f8fdf8; - border-radius: 12px; - border: 2px solid #e8f5e8; -} - -.length-slider { - flex: 1; - height: 6px; - background: #e8f5e8; - border-radius: 3px; - outline: none; - -webkit-appearance: none; -} - -.length-slider::-webkit-slider-thumb { - -webkit-appearance: none; - width: 20px; - height: 20px; - background: linear-gradient(135deg, #4caf50, #45a049); - border-radius: 50%; - cursor: pointer; - box-shadow: 0 2px 8px rgba(76, 175, 80, 0.3); -} - -.length-slider::-moz-range-thumb { - width: 20px; - height: 20px; - background: linear-gradient(135deg, #4caf50, #45a049); - border-radius: 50%; - cursor: pointer; - border: none; - box-shadow: 0 2px 8px rgba(76, 175, 80, 0.3); -} - -.length-display { - min-width: 40px; - text-align: center; - font-weight: 700; - font-size: 1.2rem; - color: #2d5a3d; - background: #ffffff; - padding: 8px 12px; - border-radius: 8px; - border: 2px solid #e8f5e8; -} - -/* 复选框组 */ -.checkbox-group { - display: flex; - flex-direction: column; - gap: 12px; -} - -.checkbox-item { - display: flex; - align-items: center; - gap: 12px; - padding: 12px 16px; - background: #f8fdf8; - border-radius: 10px; - border: 2px solid #e8f5e8; - transition: all 0.3s ease; - cursor: pointer; -} - -.checkbox-item:hover { - background: #f0f9f0; - border-color: #d4edda; - transform: translateY(-1px); -} - -.checkbox-item input[type="checkbox"] { - width: 18px; - height: 18px; - accent-color: #4caf50; - cursor: pointer; -} - -.checkbox-item label { - flex: 1; - cursor: pointer; - font-weight: 500; - color: #2d5a3d; - margin: 0; -} - -/* 生成按钮 */ -.generate-btn { - background: linear-gradient(135deg, #4caf50, #45a049); - color: white; - border: none; - padding: 16px 32px; - border-radius: 12px; - font-size: 1.1rem; - font-weight: 600; - cursor: pointer; - transition: all 0.3s ease; - box-shadow: 0 4px 16px rgba(76, 175, 80, 0.3); - position: relative; - overflow: hidden; -} - -.generate-btn:hover { - transform: translateY(-2px); - box-shadow: 0 6px 20px rgba(76, 175, 80, 0.4); -} - -.generate-btn:active { - transform: translateY(0); -} - -.generate-btn:disabled { - opacity: 0.7; - cursor: not-allowed; - transform: none; -} - -/* 结果容器 */ -.result-container { - background: #ffffff; - border-radius: 16px; - padding: 30px; - box-shadow: 0 8px 32px rgba(45, 90, 61, 0.1); - border: 1px solid #e8f5e8; - animation: slideIn 0.5s ease-out; -} - -@keyframes slideIn { - from { - opacity: 0; - transform: translateY(20px); - } - to { - opacity: 1; - transform: translateY(0); - } -} - -.result-header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 20px; -} - -.result-header h3 { - color: #2d5a3d; - font-size: 1.3rem; - font-weight: 600; -} - -.copy-btn { - background: #4caf50; - color: white; - border: none; - padding: 10px; - border-radius: 8px; - cursor: pointer; - transition: all 0.3s ease; - display: flex; - align-items: center; - justify-content: center; -} - -.copy-btn:hover { - background: #45a049; - transform: scale(1.05); -} - -/* 密码显示 */ -.password-display { - margin-bottom: 25px; -} - -.password-input { - width: 100%; - padding: 16px 20px; - border: 2px solid #e8f5e8; - border-radius: 12px; - font-family: 'Courier New', monospace; - font-size: 1.1rem; - font-weight: 600; - color: #2d5a3d; - background: #f8fdf8; - text-align: center; - letter-spacing: 1px; - word-break: break-all; -} - -.password-input:focus { - outline: none; - border-color: #4caf50; - box-shadow: 0 0 0 3px rgba(76, 175, 80, 0.1); -} - -/* 密码信息 */ -.password-info { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); - gap: 15px; - margin-bottom: 25px; -} - -.info-item { - display: flex; - flex-direction: column; - gap: 5px; - padding: 12px 16px; - background: #f8fdf8; - border-radius: 10px; - border: 1px solid #e8f5e8; -} - -.info-item.full-width { - grid-column: 1 / -1; -} - -.info-label { - font-size: 0.9rem; - color: #5a8a6b; - font-weight: 500; -} - -.info-value { - font-size: 1rem; - color: #2d5a3d; - font-weight: 600; -} - -.info-value.strength { - padding: 4px 8px; - border-radius: 6px; - text-align: center; - color: white; - font-weight: 700; -} - -.strength.weak { - background: #f44336; -} - -.strength.medium { - background: #ff9800; -} - -.strength.strong { - background: #4caf50; -} - -.strength.very-strong { - background: #2e7d32; -} - -/* 字符集显示 */ -.character-sets { - border-top: 1px solid #e8f5e8; - padding-top: 20px; -} - -.character-sets h4 { - color: #2d5a3d; - margin-bottom: 15px; - font-size: 1.1rem; -} - -.sets-list { - display: flex; - flex-wrap: wrap; - gap: 10px; -} - -.set-item { - background: #e8f5e8; - color: #2d5a3d; - padding: 6px 12px; - border-radius: 20px; - font-size: 0.9rem; - font-weight: 500; -} - -/* 错误容器 */ -.error-container { - background: #ffffff; - border-radius: 16px; - padding: 40px 30px; - text-align: center; - box-shadow: 0 8px 32px rgba(244, 67, 54, 0.1); - border: 1px solid #ffebee; -} - -.error-icon { - font-size: 3rem; - margin-bottom: 15px; -} - -.error-container h3 { - color: #d32f2f; - margin-bottom: 10px; - font-size: 1.3rem; -} - -.error-container p { - color: #666; - margin-bottom: 20px; -} - -.retry-btn { - background: #f44336; - color: white; - border: none; - padding: 12px 24px; - border-radius: 8px; - font-weight: 600; - cursor: pointer; - transition: all 0.3s ease; -} - -.retry-btn:hover { - background: #d32f2f; - transform: translateY(-1px); -} - -/* 页脚 */ -.footer { - text-align: center; - padding: 30px 20px; - color: #5a8a6b; - font-size: 0.9rem; -} - -/* 提示框 */ -.toast { - position: fixed; - top: 20px; - right: 20px; - background: #4caf50; - color: white; - padding: 12px 20px; - border-radius: 8px; - box-shadow: 0 4px 12px rgba(76, 175, 80, 0.3); - z-index: 1000; - animation: toastSlide 0.3s ease-out; -} - -@keyframes toastSlide { - from { - transform: translateX(100%); - opacity: 0; - } - to { - transform: translateX(0); - opacity: 1; - } -} - -/* 平板端适配 (768px - 1024px) */ -@media (min-width: 768px) and (max-width: 1024px) { - .container { - max-width: 700px; - padding: 25px; - } - - .header h1 { - font-size: 2.2rem; - } - - .form-container, - .result-container { - padding: 25px; - } - - .password-info { - grid-template-columns: repeat(2, 1fr); - } -} - -/* 手机端适配 (最大767px) */ -@media (max-width: 767px) { - .container { - padding: 15px; - max-width: 100%; - } - - .header { - padding: 20px 15px; - margin-bottom: 25px; - } - - .header h1 { - font-size: 1.8rem; - } - - .subtitle { - font-size: 1rem; - } - - .form-container, - .result-container { - padding: 20px; - border-radius: 12px; - } - - .password-form { - gap: 20px; - } - - .form-group { - gap: 10px; - } - - .length-control { - padding: 12px; - gap: 12px; - } - - .length-display { - min-width: 35px; - padding: 6px 10px; - font-size: 1.1rem; - } - - .checkbox-item { - padding: 10px 12px; - gap: 10px; - } - - .checkbox-item input[type="checkbox"] { - width: 16px; - height: 16px; - } - - .generate-btn { - padding: 14px 28px; - font-size: 1rem; - } - - .password-input { - padding: 14px 16px; - font-size: 1rem; - letter-spacing: 0.5px; - } - - .password-info { - grid-template-columns: 1fr; - gap: 12px; - } - - .info-item { - padding: 10px 12px; - } - - .result-header { - flex-direction: column; - gap: 15px; - align-items: stretch; - } - - .copy-btn { - align-self: center; - padding: 12px 20px; - border-radius: 10px; - } - - .toast { - right: 15px; - left: 15px; - top: 15px; - text-align: center; - } -} - -/* 小屏手机适配 (最大480px) */ -@media (max-width: 480px) { - .container { - padding: 10px; - } - - .header { - padding: 15px 10px; - margin-bottom: 20px; - } - - .header h1 { - font-size: 1.6rem; - } - - .form-container, - .result-container { - padding: 15px; - } - - .checkbox-item { - padding: 8px 10px; - } - - .generate-btn { - padding: 12px 24px; - } - - .password-input { - padding: 12px 14px; - font-size: 0.95rem; - } -} - -/* 触摸设备优化 */ -@media (hover: none) and (pointer: coarse) { - .checkbox-item, - .generate-btn, - .copy-btn, - .retry-btn { - min-height: 44px; - } - - .checkbox-item input[type="checkbox"] { - width: 20px; - height: 20px; - } - - .length-slider::-webkit-slider-thumb { - width: 24px; - height: 24px; - } -} - -/* 高对比度模式支持 */ -@media (prefers-contrast: high) { - .form-container, - .result-container { - border: 2px solid #2d5a3d; - } - - .checkbox-item { - border: 1px solid #2d5a3d; - } - - .password-input { - border: 2px solid #2d5a3d; - } -} - -/* 减少动画模式支持 */ -@media (prefers-reduced-motion: reduce) { - * { - animation-duration: 0.01ms !important; - animation-iteration-count: 1 !important; - transition-duration: 0.01ms !important; - } -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/随机密码生成器/index.html b/frontend/60sapi/实用功能/随机密码生成器/index.html deleted file mode 100644 index baada2f2..00000000 --- a/frontend/60sapi/实用功能/随机密码生成器/index.html +++ /dev/null @@ -1,146 +0,0 @@ - - - - - - 随机密码生成器 - - - - -
    -
    -

    🔐 随机密码生成器

    -

    生成安全可靠的随机密码

    -
    - -
    -
    -
    -
    - -
    - - 16 -
    -
    - -
    - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    -
    - -
    - -
    -
    - - -
    -
    - - -
    -
    -
    - - -
    -
    - - - - -
    - -
    -

    安全密码生成工具

    -
    -
    - - - - - - \ No newline at end of file diff --git a/frontend/60sapi/实用功能/随机密码生成器/js/script.js b/frontend/60sapi/实用功能/随机密码生成器/js/script.js deleted file mode 100644 index a8e56061..00000000 --- a/frontend/60sapi/实用功能/随机密码生成器/js/script.js +++ /dev/null @@ -1,412 +0,0 @@ -class PasswordGenerator { - constructor() { - this.apiUrl = 'https://60s.api.shumengya.top/v2/password'; - this.loadStartTime = 0; - this.init(); - } - - init() { - this.bindEvents(); - this.updateLengthDisplay(); - this.preloadResources(); - } - - preloadResources() { - // 预连接API服务器 - const link = document.createElement('link'); - link.rel = 'preconnect'; - link.href = 'https://60s.api.shumengya.top'; - document.head.appendChild(link); - } - - bindEvents() { - // 长度滑块事件 - const lengthSlider = document.getElementById('length'); - lengthSlider.addEventListener('input', () => this.updateLengthDisplay()); - - // 生成按钮事件 - const generateBtn = document.getElementById('generateBtn'); - generateBtn.addEventListener('click', () => this.generatePassword()); - - // 复制按钮事件 - const copyBtn = document.getElementById('copyBtn'); - copyBtn.addEventListener('click', () => this.copyPassword()); - - // 重试按钮事件 - const retryBtn = document.getElementById('retryBtn'); - retryBtn.addEventListener('click', () => this.generatePassword()); - - // 复选框变化事件 - const checkboxes = document.querySelectorAll('input[type="checkbox"]'); - checkboxes.forEach(checkbox => { - checkbox.addEventListener('change', () => this.validateForm()); - }); - - // 键盘快捷键 - document.addEventListener('keydown', (e) => { - if (e.ctrlKey && e.key === 'Enter') { - e.preventDefault(); - this.generatePassword(); - } - if (e.ctrlKey && e.key === 'c' && document.activeElement.id === 'passwordResult') { - this.copyPassword(); - } - }); - } - - updateLengthDisplay() { - const lengthSlider = document.getElementById('length'); - const lengthDisplay = document.getElementById('lengthDisplay'); - lengthDisplay.textContent = lengthSlider.value; - } - - validateForm() { - const checkboxes = document.querySelectorAll('input[type="checkbox"]:checked'); - const generateBtn = document.getElementById('generateBtn'); - - // 至少需要选择一种字符类型 - const hasCharacterType = Array.from(checkboxes).some(cb => - ['numbers', 'uppercase', 'lowercase', 'symbols'].includes(cb.id) - ); - - generateBtn.disabled = !hasCharacterType; - - if (!hasCharacterType) { - this.showToast('请至少选择一种字符类型', 'warning'); - } - } - - async generatePassword() { - this.loadStartTime = Date.now(); - - try { - this.showLoading(true); - this.hideError(); - - const params = this.getFormParams(); - const password = await this.callAPI(params); - - if (password) { - this.displayPassword(password, params); - this.showToast('密码生成成功!', 'success'); - - const loadTime = Date.now() - this.loadStartTime; - console.log(`密码生成完成,耗时: ${loadTime}ms`); - } - } catch (error) { - console.error('生成密码失败:', error); - this.showError(error.message || '生成密码时发生错误,请重试'); - } finally { - this.showLoading(false); - } - } - - getFormParams() { - const length = document.getElementById('length').value; - const numbers = document.getElementById('numbers').checked; - const uppercase = document.getElementById('uppercase').checked; - const lowercase = document.getElementById('lowercase').checked; - const symbols = document.getElementById('symbols').checked; - const excludeSimilar = document.getElementById('excludeSimilar').checked; - const excludeAmbiguous = document.getElementById('excludeAmbiguous').checked; - - return { - length: parseInt(length), - numbers: numbers ? 'true' : 'false', - uppercase: uppercase ? 'true' : 'false', - lowercase: lowercase ? 'true' : 'false', - symbols: symbols ? 'true' : 'false', - exclude_similar: excludeSimilar ? 'true' : 'false', - exclude_ambiguous: excludeAmbiguous ? 'true' : 'false', - encoding: 'json' - }; - } - - async callAPI(params) { - const controller = new AbortController(); - const timeoutId = setTimeout(() => controller.abort(), 5000); - - try { - const url = new URL(this.apiUrl); - Object.keys(params).forEach(key => { - if (params[key] !== undefined && params[key] !== null) { - url.searchParams.append(key, params[key]); - } - }); - - const response = await fetch(url.toString(), { - method: 'GET', - signal: controller.signal, - headers: { - 'Accept': 'application/json', - 'User-Agent': 'PasswordGenerator/1.0' - } - }); - - 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.password) { - return data.data.password; - } else { - throw new Error(data.message || '服务器返回了无效的密码数据'); - } - } catch (error) { - clearTimeout(timeoutId); - - if (error.name === 'AbortError') { - throw new Error('请求超时,请检查网络连接后重试'); - } - - if (error.message.includes('Failed to fetch')) { - throw new Error('网络连接失败,请检查网络后重试'); - } - - throw error; - } - } - - displayPassword(password, params) { - // 显示结果容器 - const resultContainer = document.getElementById('resultContainer'); - const errorContainer = document.getElementById('errorContainer'); - - resultContainer.style.display = 'block'; - errorContainer.style.display = 'none'; - - // 设置密码 - const passwordInput = document.getElementById('passwordResult'); - passwordInput.value = password; - - // 计算并显示密码信息 - this.updatePasswordInfo(password, params); - - // 滚动到结果区域 - resultContainer.scrollIntoView({ behavior: 'smooth', block: 'start' }); - } - - updatePasswordInfo(password, params) { - // 基本信息 - document.getElementById('infoLength').textContent = password.length; - document.getElementById('infoEntropy').textContent = this.calculateEntropy(password).toFixed(1); - - // 密码强度 - const strength = this.calculateStrength(password); - const strengthElement = document.getElementById('infoStrength'); - strengthElement.textContent = strength.text; - strengthElement.className = `info-value strength ${strength.class}`; - - // 字符类型统计 - const stats = this.analyzeCharacters(password); - document.getElementById('infoNumbers').textContent = stats.numbers; - document.getElementById('infoUppercase').textContent = stats.uppercase; - document.getElementById('infoLowercase').textContent = stats.lowercase; - document.getElementById('infoSymbols').textContent = stats.symbols; - - // 使用的字符集 - this.updateCharacterSets(params); - - // 破解时间估算 - document.getElementById('infoCrackTime').textContent = this.estimateCrackTime(password); - } - - calculateEntropy(password) { - const charset = this.getCharsetSize(password); - return Math.log2(Math.pow(charset, password.length)); - } - - getCharsetSize(password) { - let size = 0; - if (/[0-9]/.test(password)) size += 10; - if (/[a-z]/.test(password)) size += 26; - if (/[A-Z]/.test(password)) size += 26; - if (/[^a-zA-Z0-9]/.test(password)) size += 32; - return size; - } - - calculateStrength(password) { - const entropy = this.calculateEntropy(password); - - if (entropy < 30) { - return { text: '弱', class: 'weak' }; - } else if (entropy < 50) { - return { text: '中等', class: 'medium' }; - } else if (entropy < 70) { - return { text: '强', class: 'strong' }; - } else { - return { text: '非常强', class: 'very-strong' }; - } - } - - analyzeCharacters(password) { - return { - numbers: (password.match(/[0-9]/g) || []).length, - uppercase: (password.match(/[A-Z]/g) || []).length, - lowercase: (password.match(/[a-z]/g) || []).length, - symbols: (password.match(/[^a-zA-Z0-9]/g) || []).length - }; - } - - updateCharacterSets(params) { - const setsList = document.getElementById('setsList'); - const sets = []; - - if (params.numbers === 'true') sets.push('数字 (0-9)'); - if (params.uppercase === 'true') sets.push('大写字母 (A-Z)'); - if (params.lowercase === 'true') sets.push('小写字母 (a-z)'); - if (params.symbols === 'true') sets.push('特殊字符 (!@#$...)'); - - setsList.innerHTML = sets.map(set => `${set}`).join(''); - } - - estimateCrackTime(password) { - const charset = this.getCharsetSize(password); - const combinations = Math.pow(charset, password.length); - const guessesPerSecond = 1e9; // 假设每秒10亿次尝试 - const secondsToCrack = combinations / (2 * guessesPerSecond); - - if (secondsToCrack < 60) { - return '不到1分钟'; - } else if (secondsToCrack < 3600) { - return `${Math.ceil(secondsToCrack / 60)}分钟`; - } else if (secondsToCrack < 86400) { - return `${Math.ceil(secondsToCrack / 3600)}小时`; - } else if (secondsToCrack < 31536000) { - return `${Math.ceil(secondsToCrack / 86400)}天`; - } else if (secondsToCrack < 31536000000) { - return `${Math.ceil(secondsToCrack / 31536000)}年`; - } else { - return '数千年以上'; - } - } - - async copyPassword() { - const passwordInput = document.getElementById('passwordResult'); - - try { - if (navigator.clipboard && window.isSecureContext) { - await navigator.clipboard.writeText(passwordInput.value); - } else { - // 降级方案 - passwordInput.select(); - passwordInput.setSelectionRange(0, 99999); - document.execCommand('copy'); - } - - this.showToast('密码已复制到剪贴板!', 'success'); - - // 复制按钮反馈 - const copyBtn = document.getElementById('copyBtn'); - const originalText = copyBtn.innerHTML; - copyBtn.innerHTML = '✓ 已复制'; - copyBtn.style.background = '#2e7d32'; - - setTimeout(() => { - copyBtn.innerHTML = originalText; - copyBtn.style.background = ''; - }, 2000); - - } catch (error) { - console.error('复制失败:', error); - this.showToast('复制失败,请手动选择密码', 'error'); - } - } - - showLoading(show) { - const generateBtn = document.getElementById('generateBtn'); - - if (show) { - generateBtn.disabled = true; - generateBtn.innerHTML = ' 生成中...'; - } else { - generateBtn.disabled = false; - generateBtn.innerHTML = '🔐 生成密码'; - } - } - - showError(message) { - const errorContainer = document.getElementById('errorContainer'); - const resultContainer = document.getElementById('resultContainer'); - const errorMessage = document.getElementById('errorMessage'); - - errorMessage.textContent = message; - errorContainer.style.display = 'block'; - resultContainer.style.display = 'none'; - - errorContainer.scrollIntoView({ behavior: 'smooth', block: 'start' }); - } - - hideError() { - const errorContainer = document.getElementById('errorContainer'); - errorContainer.style.display = 'none'; - } - - showToast(message, type = 'info') { - // 移除现有的toast - const existingToast = document.querySelector('.toast'); - if (existingToast) { - existingToast.remove(); - } - - const toast = document.createElement('div'); - toast.className = 'toast'; - toast.textContent = message; - - // 根据类型设置颜色 - const colors = { - success: '#4caf50', - error: '#f44336', - warning: '#ff9800', - info: '#2196f3' - }; - - toast.style.background = colors[type] || colors.info; - - document.body.appendChild(toast); - - // 3秒后自动移除 - setTimeout(() => { - if (toast.parentNode) { - toast.remove(); - } - }, 3000); - } -} - -// 添加旋转动画样式 -const style = document.createElement('style'); -style.textContent = ` - @keyframes spin { - from { transform: rotate(0deg); } - to { transform: rotate(360deg); } - } -`; -document.head.appendChild(style); - -// 页面加载完成后初始化 -document.addEventListener('DOMContentLoaded', () => { - new PasswordGenerator(); -}); - -// 页面可见性变化时的处理 -document.addEventListener('visibilitychange', () => { - if (document.visibilityState === 'visible') { - // 页面重新可见时,可以进行一些刷新操作 - console.log('页面重新可见'); - } -}); - -// 错误处理 -window.addEventListener('error', (event) => { - console.error('全局错误:', event.error); -}); - -window.addEventListener('unhandledrejection', (event) => { - console.error('未处理的Promise拒绝:', event.reason); - event.preventDefault(); -}); \ No newline at end of file diff --git a/frontend/60sapi/实用功能/随机密码生成器/返回接口.json b/frontend/60sapi/实用功能/随机密码生成器/返回接口.json deleted file mode 100644 index 3b91a5e8..00000000 --- a/frontend/60sapi/实用功能/随机密码生成器/返回接口.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "code": 200, - "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", - "data": { - "password": "8mr2M7dZ6E3saj3F", - "length": 16, - "config": { - "include_numbers": true, - "include_symbols": false, - "include_lowercase": true, - "include_uppercase": true, - "exclude_similar": true, - "exclude_ambiguous": true - }, - "character_sets": { - "lowercase": "abcdefghjkmnpqrstuvwxyz", - "uppercase": "ABCDEFGHIJKMNPQRSTUVWXYZ", - "numbers": "23456789", - "symbols": "", - "used_sets": [ - "lowercase", - "uppercase", - "numbers" - ] - }, - "generation_info": { - "entropy": 92.5, - "strength": "极强", - "time_to_crack": "数百万年" - } - } -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/随机颜色/background.css b/frontend/60sapi/实用功能/随机颜色/background.css deleted file mode 100644 index 81e610a9..00000000 --- a/frontend/60sapi/实用功能/随机颜色/background.css +++ /dev/null @@ -1,215 +0,0 @@ -/* 背景样式文件 - 独立管理背景相关样式 */ - -/* 主体背景 */ -body { - background: linear-gradient(135deg, #e8f5e8 0%, #f0fff0 50%, #e8f5e8 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%; - } -} - -/* 容器背景装饰 */ -.container::before { - content: ''; - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-image: - radial-gradient(circle at 20% 80%, rgba(144, 205, 144, 0.1) 0%, transparent 50%), - radial-gradient(circle at 80% 20%, rgba(45, 90, 39, 0.05) 0%, transparent 50%), - radial-gradient(circle at 40% 40%, rgba(144, 205, 144, 0.08) 0%, transparent 50%); - pointer-events: none; - z-index: -1; -} - -/* 输入区域背景 */ -.input-section { - background: rgba(255, 255, 255, 0.95); - backdrop-filter: blur(10px); - -webkit-backdrop-filter: blur(10px); -} - -/* 结果区域背景 */ -.result-section { - background: rgba(255, 255, 255, 0.95); - backdrop-filter: blur(10px); - -webkit-backdrop-filter: blur(10px); -} - -/* 格式组背景 */ -.format-group { - background: rgba(248, 255, 248, 0.8); - backdrop-filter: blur(5px); - -webkit-backdrop-filter: blur(5px); -} - -/* 属性项背景 */ -.property-item { - background: rgba(248, 255, 248, 0.8); - backdrop-filter: blur(5px); - -webkit-backdrop-filter: blur(5px); -} - -/* 调色板项背景 */ -.palette-item { - background: rgba(248, 255, 248, 0.8); - backdrop-filter: blur(5px); - -webkit-backdrop-filter: blur(5px); -} - -/* 无障碍项背景 */ -.accessibility-item { - background: rgba(248, 255, 248, 0.8); - backdrop-filter: blur(5px); - -webkit-backdrop-filter: blur(5px); -} - -/* 颜色预览背景 */ -.color-preview { - background: rgba(248, 255, 248, 0.6); - backdrop-filter: blur(8px); - -webkit-backdrop-filter: blur(8px); -} - -/* 输入框背景 */ -.input-group input, -.input-group select { - background: rgba(248, 255, 248, 0.9); - backdrop-filter: blur(5px); - -webkit-backdrop-filter: blur(5px); -} - -.input-group input:focus, -.input-group select:focus { - background: rgba(255, 255, 255, 0.95); -} - -/* 格式组内部元素背景 */ -.format-group p { - background: rgba(255, 255, 255, 0.9); - backdrop-filter: blur(3px); - -webkit-backdrop-filter: blur(3px); -} - -/* 手机端背景优化 */ -@media (max-width: 767px) { - body { - background: linear-gradient(180deg, #e8f5e8 0%, #f0fff0 50%, #e8f5e8 100%); - background-attachment: scroll; /* 手机端使用scroll避免性能问题 */ - } - - .container::before { - background-image: - radial-gradient(circle at 30% 70%, rgba(144, 205, 144, 0.08) 0%, transparent 40%), - radial-gradient(circle at 70% 30%, rgba(45, 90, 39, 0.04) 0%, transparent 40%); - } - - /* 减少手机端的模糊效果以提升性能 */ - .input-section, - .result-section { - backdrop-filter: blur(5px); - -webkit-backdrop-filter: blur(5px); - } - - .format-group, - .property-item, - .palette-item, - .accessibility-item { - backdrop-filter: blur(3px); - -webkit-backdrop-filter: blur(3px); - } -} - -/* 平板端背景优化 */ -@media (min-width: 768px) and (max-width: 1024px) { - .container::before { - background-image: - radial-gradient(circle at 25% 75%, rgba(144, 205, 144, 0.12) 0%, transparent 60%), - radial-gradient(circle at 75% 25%, rgba(45, 90, 39, 0.06) 0%, transparent 60%), - radial-gradient(circle at 50% 50%, rgba(144, 205, 144, 0.04) 0%, transparent 40%); - } -} - -/* 电脑端背景优化 */ -@media (min-width: 1025px) { - body { - background-size: 300% 300%; - animation-duration: 20s; - } - - .container::before { - background-image: - radial-gradient(circle at 15% 85%, rgba(144, 205, 144, 0.15) 0%, transparent 70%), - radial-gradient(circle at 85% 15%, rgba(45, 90, 39, 0.08) 0%, transparent 70%), - radial-gradient(circle at 35% 35%, rgba(144, 205, 144, 0.1) 0%, transparent 50%), - radial-gradient(circle at 65% 65%, rgba(45, 90, 39, 0.05) 0%, transparent 50%); - } - - /* 电脑端增强模糊效果 */ - .input-section, - .result-section { - backdrop-filter: blur(15px); - -webkit-backdrop-filter: blur(15px); - } - - .format-group, - .property-item, - .palette-item, - .accessibility-item { - backdrop-filter: blur(8px); - -webkit-backdrop-filter: blur(8px); - } -} - -/* 深色模式支持(如果用户系统设置为深色模式) */ -@media (prefers-color-scheme: dark) { - body { - background: linear-gradient(135deg, #1a2e1a 0%, #0f1f0f 50%, #1a2e1a 100%); - } - - .container::before { - background-image: - radial-gradient(circle at 20% 80%, rgba(144, 205, 144, 0.05) 0%, transparent 50%), - radial-gradient(circle at 80% 20%, rgba(45, 90, 39, 0.03) 0%, transparent 50%); - } - - .input-section, - .result-section { - background: rgba(26, 46, 26, 0.9); - } - - .format-group, - .property-item, - .palette-item, - .accessibility-item, - .color-preview { - background: rgba(26, 46, 26, 0.6); - } - - .input-group input, - .input-group select { - background: rgba(26, 46, 26, 0.8); - color: #e8f5e8; - border-color: rgba(144, 205, 144, 0.3); - } - - .format-group p { - background: rgba(15, 31, 15, 0.8); - color: #e8f5e8; - } -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/随机颜色/index.html b/frontend/60sapi/实用功能/随机颜色/index.html deleted file mode 100644 index cf9be12c..00000000 --- a/frontend/60sapi/实用功能/随机颜色/index.html +++ /dev/null @@ -1,187 +0,0 @@ - - - - - - 随机颜色/颜色转换工具 - - - - -
    -
    -

    随机颜色/颜色转换工具

    -

    获取随机颜色或转换指定颜色格式

    -
    - -
    -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - -
    -
    -
    -
    -

    颜色名称

    -

    #000000

    -
    -
    - -
    -
    -

    RGB

    -
    - 0 - 0 - 0 -
    -

    rgb(0, 0, 0)

    -
    - -
    -

    HSL

    -
    - - 0% - 0% -
    -

    hsl(0, 0%, 0%)

    -
    - -
    -

    HSV

    -
    - - 0% - 0% -
    -

    hsv(0, 0%, 0%)

    -
    - -
    -

    CMYK

    -
    - 0% - 0% - 0% - 0% -
    -

    cmyk(0%, 0%, 0%, 0%)

    -
    - -
    -

    LAB

    -
    - 0 - 0 - 0 -
    -

    lab(0, 0, 0)

    -
    -
    - -
    -
    - - 0 -
    -
    - - 0 -
    -
    - - 0 -
    -
    - - #000000 -
    -
    - -
    -

    配色方案

    -
    -
    - -
    - #000000 -
    -
    - -
    -
    -
    -
    -
    - #000000 - #000000 -
    -
    -
    - -
    -
    -
    -
    -
    - #000000 - #000000 -
    -
    -
    -
    - -
    -

    无障碍性

    -
    -
    - AA 普通文本: - -
    -
    - AA 大文本: - -
    -
    - AAA 普通文本: - -
    -
    - AAA 大文本: - -
    -
    -
    -
    - - - - -
    -
    - - - - \ No newline at end of file diff --git a/frontend/60sapi/实用功能/随机颜色/script.js b/frontend/60sapi/实用功能/随机颜色/script.js deleted file mode 100644 index e641efe4..00000000 --- a/frontend/60sapi/实用功能/随机颜色/script.js +++ /dev/null @@ -1,426 +0,0 @@ -// 随机颜色/颜色转换工具 JavaScript - -class ColorTool { - constructor() { - this.apiUrl = 'https://60s.api.shumengya.top/v2/color'; - this.init(); - } - - init() { - this.bindEvents(); - this.hideResultSection(); - } - - bindEvents() { - const randomBtn = document.getElementById('randomBtn'); - const convertBtn = document.getElementById('convertBtn'); - const colorInput = document.getElementById('colorInput'); - - randomBtn.addEventListener('click', () => this.getRandomColor()); - convertBtn.addEventListener('click', () => this.convertColor()); - - // 回车键支持 - colorInput.addEventListener('keypress', (e) => { - if (e.key === 'Enter') { - this.convertColor(); - } - }); - } - - hideResultSection() { - const resultSection = document.querySelector('.result-section'); - resultSection.style.display = 'none'; - } - - showResultSection() { - const resultSection = document.querySelector('.result-section'); - resultSection.style.display = 'block'; - } - - showLoading() { - const loading = document.getElementById('loading'); - const error = document.getElementById('error'); - loading.style.display = 'block'; - error.style.display = 'none'; - this.hideResultSection(); - } - - hideLoading() { - const loading = document.getElementById('loading'); - loading.style.display = 'none'; - } - - showError(message) { - const error = document.getElementById('error'); - const errorMessage = document.getElementById('errorMessage'); - const loading = document.getElementById('loading'); - - loading.style.display = 'none'; - errorMessage.textContent = message; - error.style.display = 'block'; - this.hideResultSection(); - } - - hideError() { - const error = document.getElementById('error'); - error.style.display = 'none'; - } - - async getRandomColor() { - try { - this.showLoading(); - const encoding = document.getElementById('encodingSelect').value; - const url = `${this.apiUrl}?encoding=${encoding}`; - - const response = await fetch(url); - if (!response.ok) { - throw new Error(`HTTP ${response.status}: ${response.statusText}`); - } - - const data = await response.json(); - - if (data.code === 200) { - this.displayColorData(data.data); - this.hideLoading(); - this.hideError(); - this.showResultSection(); - } else { - throw new Error(data.message || '获取颜色信息失败'); - } - } catch (error) { - console.error('获取随机颜色失败:', error); - this.showError(`获取随机颜色失败: ${error.message}`); - } - } - - async convertColor() { - const colorInput = document.getElementById('colorInput'); - const colorValue = colorInput.value.trim(); - - if (!colorValue) { - this.showError('请输入要转换的颜色值'); - return; - } - - // 简单的颜色格式验证 - if (!this.isValidColor(colorValue)) { - this.showError('请输入有效的颜色值(如 #33AAFF)'); - return; - } - - try { - this.showLoading(); - const encoding = document.getElementById('encodingSelect').value; - const url = `${this.apiUrl}?color=${encodeURIComponent(colorValue)}&encoding=${encoding}`; - - const response = await fetch(url); - if (!response.ok) { - throw new Error(`HTTP ${response.status}: ${response.statusText}`); - } - - const data = await response.json(); - - if (data.code === 200) { - this.displayColorData(data.data); - this.hideLoading(); - this.hideError(); - this.showResultSection(); - } else { - throw new Error(data.message || '转换颜色失败'); - } - } catch (error) { - console.error('转换颜色失败:', error); - this.showError(`转换颜色失败: ${error.message}`); - } - } - - isValidColor(color) { - // 支持十六进制颜色格式 - const hexPattern = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/; - // 支持RGB格式 - const rgbPattern = /^rgb\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*\)$/; - // 支持HSL格式 - const hslPattern = /^hsl\(\s*\d+\s*,\s*\d+%\s*,\s*\d+%\s*\)$/; - - return hexPattern.test(color) || rgbPattern.test(color) || hslPattern.test(color); - } - - displayColorData(data) { - // 显示主要颜色信息 - this.updateColorDisplay(data); - - // 显示各种格式 - this.updateColorFormats(data); - - // 显示颜色属性 - this.updateColorProperties(data); - - // 显示配色方案 - this.updateColorPalette(data); - - // 显示无障碍性信息 - this.updateAccessibilityInfo(data); - } - - updateColorDisplay(data) { - const colorDisplay = document.getElementById('colorDisplay'); - const colorName = document.getElementById('colorName'); - const hexValue = document.getElementById('hexValue'); - - colorDisplay.style.backgroundColor = data.hex; - colorName.textContent = data.name || '未知颜色'; - hexValue.textContent = data.hex; - } - - updateColorFormats(data) { - // RGB - if (data.rgb) { - document.getElementById('rgbR').textContent = data.rgb.r; - document.getElementById('rgbG').textContent = data.rgb.g; - document.getElementById('rgbB').textContent = data.rgb.b; - document.getElementById('rgbString').textContent = data.rgb.string; - } - - // HSL - if (data.hsl) { - document.getElementById('hslH').textContent = data.hsl.h + '°'; - document.getElementById('hslS').textContent = data.hsl.s + '%'; - document.getElementById('hslL').textContent = data.hsl.l + '%'; - document.getElementById('hslString').textContent = data.hsl.string; - } - - // HSV - if (data.hsv) { - document.getElementById('hsvH').textContent = data.hsv.h + '°'; - document.getElementById('hsvS').textContent = data.hsv.s + '%'; - document.getElementById('hsvV').textContent = data.hsv.v + '%'; - document.getElementById('hsvString').textContent = data.hsv.string; - } - - // CMYK - if (data.cmyk) { - document.getElementById('cmykC').textContent = data.cmyk.c + '%'; - document.getElementById('cmykM').textContent = data.cmyk.m + '%'; - document.getElementById('cmykY').textContent = data.cmyk.y + '%'; - document.getElementById('cmykK').textContent = data.cmyk.k + '%'; - document.getElementById('cmykString').textContent = data.cmyk.string; - } - - // LAB - if (data.lab) { - document.getElementById('labL').textContent = data.lab.l; - document.getElementById('labA').textContent = data.lab.a; - document.getElementById('labB').textContent = data.lab.b; - document.getElementById('labString').textContent = data.lab.string; - } - } - - updateColorProperties(data) { - // 亮度 - if (data.brightness !== undefined) { - document.getElementById('brightness').textContent = data.brightness.toFixed(2); - } - - // 对比度 - if (data.contrast) { - document.getElementById('contrastWhite').textContent = data.contrast.white.toFixed(2); - document.getElementById('contrastBlack').textContent = data.contrast.black.toFixed(2); - } - - // 最佳文字颜色 - if (data.accessibility && data.accessibility.best_text_color) { - const bestTextColor = document.getElementById('bestTextColor'); - bestTextColor.textContent = data.accessibility.best_text_color; - bestTextColor.style.color = data.accessibility.best_text_color; - } - } - - updateColorPalette(data) { - // 互补色 - if (data.complementary) { - const complementary = document.getElementById('complementary'); - const complementaryHex = document.getElementById('complementaryHex'); - complementary.style.backgroundColor = data.complementary; - complementaryHex.textContent = data.complementary; - } - - // 类似色 - if (data.analogous && data.analogous.length >= 2) { - const analogous1 = document.getElementById('analogous1'); - const analogous2 = document.getElementById('analogous2'); - const analogous1Hex = document.getElementById('analogous1Hex'); - const analogous2Hex = document.getElementById('analogous2Hex'); - - analogous1.style.backgroundColor = data.analogous[0]; - analogous2.style.backgroundColor = data.analogous[1]; - analogous1Hex.textContent = data.analogous[0]; - analogous2Hex.textContent = data.analogous[1]; - } - - // 三角色 - if (data.triadic && data.triadic.length >= 2) { - const triadic1 = document.getElementById('triadic1'); - const triadic2 = document.getElementById('triadic2'); - const triadic1Hex = document.getElementById('triadic1Hex'); - const triadic2Hex = document.getElementById('triadic2Hex'); - - triadic1.style.backgroundColor = data.triadic[0]; - triadic2.style.backgroundColor = data.triadic[1]; - triadic1Hex.textContent = data.triadic[0]; - triadic2Hex.textContent = data.triadic[1]; - } - } - - updateAccessibilityInfo(data) { - if (data.accessibility) { - const aaNormal = document.getElementById('aaNormal'); - const aaLarge = document.getElementById('aaLarge'); - const aaaNormal = document.getElementById('aaaNormal'); - const aaaLarge = document.getElementById('aaaLarge'); - - this.updateAccessibilityStatus(aaNormal, data.accessibility.aa_normal); - this.updateAccessibilityStatus(aaLarge, data.accessibility.aa_large); - this.updateAccessibilityStatus(aaaNormal, data.accessibility.aaa_normal); - this.updateAccessibilityStatus(aaaLarge, data.accessibility.aaa_large); - } - } - - updateAccessibilityStatus(element, status) { - element.textContent = status ? '通过' : '未通过'; - element.className = 'status ' + (status ? 'pass' : 'fail'); - } - - // 复制颜色值到剪贴板 - copyToClipboard(text) { - if (navigator.clipboard) { - navigator.clipboard.writeText(text).then(() => { - this.showToast('已复制到剪贴板'); - }).catch(err => { - console.error('复制失败:', err); - this.fallbackCopyTextToClipboard(text); - }); - } else { - this.fallbackCopyTextToClipboard(text); - } - } - - fallbackCopyTextToClipboard(text) { - const textArea = document.createElement('textarea'); - textArea.value = text; - textArea.style.top = '0'; - textArea.style.left = '0'; - textArea.style.position = 'fixed'; - - document.body.appendChild(textArea); - textArea.focus(); - textArea.select(); - - try { - const successful = document.execCommand('copy'); - if (successful) { - this.showToast('已复制到剪贴板'); - } else { - this.showToast('复制失败'); - } - } catch (err) { - console.error('复制失败:', err); - this.showToast('复制失败'); - } - - document.body.removeChild(textArea); - } - - showToast(message) { - // 创建简单的提示框 - const toast = document.createElement('div'); - toast.textContent = message; - toast.style.cssText = ` - position: fixed; - top: 20px; - right: 20px; - background: #2d5a27; - color: white; - padding: 12px 20px; - border-radius: 8px; - z-index: 1000; - font-size: 14px; - box-shadow: 0 4px 12px rgba(0,0,0,0.15); - animation: slideIn 0.3s ease; - `; - - // 添加动画样式 - 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); - - setTimeout(() => { - toast.style.animation = 'slideIn 0.3s ease reverse'; - setTimeout(() => { - document.body.removeChild(toast); - document.head.removeChild(style); - }, 300); - }, 2000); - } -} - -// 添加点击复制功能 -function addCopyListeners() { - const colorTool = window.colorTool; - - // 为所有颜色值添加点击复制功能 - document.addEventListener('click', (e) => { - const target = e.target; - - // 检查是否点击了颜色值相关元素 - if (target.id === 'hexValue' || - target.id === 'rgbString' || - target.id === 'hslString' || - target.id === 'hsvString' || - target.id === 'cmykString' || - target.id === 'labString' || - target.id === 'complementaryHex' || - target.id === 'analogous1Hex' || - target.id === 'analogous2Hex' || - target.id === 'triadic1Hex' || - target.id === 'triadic2Hex') { - - const text = target.textContent; - if (text && colorTool) { - colorTool.copyToClipboard(text); - } - } - }); -} - -// 页面加载完成后初始化 -document.addEventListener('DOMContentLoaded', () => { - window.colorTool = new ColorTool(); - addCopyListeners(); - - // 添加复制提示 - const style = document.createElement('style'); - style.textContent = ` - #hexValue, #rgbString, #hslString, #hsvString, #cmykString, #labString, - #complementaryHex, #analogous1Hex, #analogous2Hex, #triadic1Hex, #triadic2Hex { - cursor: pointer; - transition: all 0.2s ease; - } - - #hexValue:hover, #rgbString:hover, #hslString:hover, #hsvString:hover, - #cmykString:hover, #labString:hover, #complementaryHex:hover, - #analogous1Hex:hover, #analogous2Hex:hover, #triadic1Hex:hover, #triadic2Hex:hover { - background: rgba(45, 90, 39, 0.1); - border-radius: 4px; - padding: 2px 4px; - margin: -2px -4px; - } - `; - document.head.appendChild(style); -}); \ No newline at end of file diff --git a/frontend/60sapi/实用功能/随机颜色/styles.css b/frontend/60sapi/实用功能/随机颜色/styles.css deleted file mode 100644 index cd53529c..00000000 --- a/frontend/60sapi/实用功能/随机颜色/styles.css +++ /dev/null @@ -1,637 +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: #2d3748; - min-height: 100vh; -} - -.container { - max-width: 1200px; - margin: 0 auto; - padding: 20px; - min-height: 100vh; -} - -/* 头部样式 */ -.header { - text-align: center; - margin-bottom: 30px; - padding: 20px 0; -} - -.header h1 { - font-size: 2rem; - color: #2d5a27; - margin-bottom: 10px; - font-weight: 600; -} - -.subtitle { - color: #4a5568; - font-size: 1rem; - opacity: 0.8; -} - -/* 主要内容区域 */ -.main-content { - display: flex; - flex-direction: column; - gap: 30px; -} - -/* 输入区域 */ -.input-section { - background: rgba(255, 255, 255, 0.9); - padding: 25px; - border-radius: 15px; - box-shadow: 0 4px 20px rgba(45, 90, 39, 0.1); - border: 1px solid rgba(144, 205, 144, 0.3); -} - -.input-group { - margin-bottom: 20px; -} - -.input-group label { - display: block; - margin-bottom: 8px; - font-weight: 500; - color: #2d5a27; - font-size: 0.95rem; -} - -.input-group input, -.input-group select { - width: 100%; - padding: 12px 15px; - border: 2px solid #90cd90; - border-radius: 10px; - font-size: 1rem; - transition: all 0.3s ease; - background: #f8fff8; -} - -.input-group input:focus, -.input-group select:focus { - outline: none; - border-color: #2d5a27; - box-shadow: 0 0 0 3px rgba(45, 90, 39, 0.1); - background: #ffffff; -} - -.button-group { - display: flex; - gap: 15px; - margin-top: 25px; -} - -.btn { - flex: 1; - padding: 15px 20px; - border: none; - border-radius: 10px; - font-size: 1rem; - font-weight: 500; - cursor: pointer; - transition: all 0.3s ease; - text-transform: none; -} - -.btn-primary { - background: linear-gradient(135deg, #2d5a27, #4a7c59); - color: white; -} - -.btn-primary:hover { - background: linear-gradient(135deg, #1e3a1a, #2d5a27); - transform: translateY(-2px); - box-shadow: 0 6px 20px rgba(45, 90, 39, 0.3); -} - -.btn-secondary { - background: linear-gradient(135deg, #90cd90, #a8d8a8); - color: #2d5a27; -} - -.btn-secondary:hover { - background: linear-gradient(135deg, #7bb87b, #90cd90); - transform: translateY(-2px); - box-shadow: 0 6px 20px rgba(144, 205, 144, 0.4); -} - -/* 结果展示区域 */ -.result-section { - background: rgba(255, 255, 255, 0.9); - padding: 25px; - border-radius: 15px; - box-shadow: 0 4px 20px rgba(45, 90, 39, 0.1); - border: 1px solid rgba(144, 205, 144, 0.3); -} - -/* 颜色预览 */ -.color-preview { - display: flex; - align-items: center; - gap: 20px; - margin-bottom: 30px; - padding: 20px; - background: #f8fff8; - border-radius: 12px; - border: 1px solid rgba(144, 205, 144, 0.2); -} - -.color-box { - width: 80px; - height: 80px; - border-radius: 12px; - border: 3px solid #ffffff; - box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1); - flex-shrink: 0; -} - -.color-info h3 { - color: #2d5a27; - margin-bottom: 5px; - font-size: 1.2rem; -} - -.color-info p { - color: #4a5568; - font-size: 1.1rem; - font-weight: 500; - font-family: 'Courier New', monospace; -} - -/* 颜色格式展示 */ -.color-formats { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); - gap: 20px; - margin-bottom: 30px; -} - -.format-group { - background: #f8fff8; - padding: 15px; - border-radius: 10px; - border: 1px solid rgba(144, 205, 144, 0.2); -} - -.format-group h4 { - color: #2d5a27; - margin-bottom: 10px; - font-size: 1rem; - font-weight: 600; -} - -.format-values { - display: flex; - gap: 8px; - margin-bottom: 8px; - flex-wrap: wrap; -} - -.format-values span { - background: #90cd90; - color: #2d5a27; - padding: 4px 8px; - border-radius: 6px; - font-size: 0.85rem; - font-weight: 500; -} - -.format-group p { - font-family: 'Courier New', monospace; - color: #4a5568; - font-size: 0.9rem; - background: #ffffff; - padding: 8px; - border-radius: 6px; - border: 1px solid rgba(144, 205, 144, 0.2); -} - -/* 颜色属性 */ -.color-properties { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); - gap: 15px; - margin-bottom: 30px; -} - -.property-item { - display: flex; - justify-content: space-between; - align-items: center; - background: #f8fff8; - padding: 12px 15px; - border-radius: 8px; - border: 1px solid rgba(144, 205, 144, 0.2); -} - -.property-item label { - color: #2d5a27; - font-weight: 500; - font-size: 0.9rem; -} - -.property-item span { - color: #4a5568; - font-weight: 600; - font-family: 'Courier New', monospace; -} - -/* 配色方案 */ -.color-palette { - margin-bottom: 30px; -} - -.color-palette h4 { - color: #2d5a27; - margin-bottom: 15px; - font-size: 1.1rem; - font-weight: 600; -} - -.palette-group { - display: flex; - flex-direction: column; - gap: 15px; -} - -.palette-item { - background: #f8fff8; - padding: 15px; - border-radius: 10px; - border: 1px solid rgba(144, 205, 144, 0.2); -} - -.palette-item label { - display: block; - color: #2d5a27; - font-weight: 500; - margin-bottom: 10px; - font-size: 0.95rem; -} - -.color-sample { - width: 40px; - height: 40px; - border-radius: 8px; - border: 2px solid #ffffff; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); - display: inline-block; - margin-right: 10px; -} - -.analogous-colors, -.triadic-colors { - display: flex; - gap: 10px; - margin-bottom: 8px; -} - -.analogous-hex, -.triadic-hex { - display: flex; - gap: 10px; - font-family: 'Courier New', monospace; - font-size: 0.85rem; - color: #4a5568; -} - -/* 无障碍性信息 */ -.accessibility-info h4 { - color: #2d5a27; - margin-bottom: 15px; - font-size: 1.1rem; - font-weight: 600; -} - -.accessibility-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); - gap: 10px; -} - -.accessibility-item { - display: flex; - justify-content: space-between; - align-items: center; - background: #f8fff8; - padding: 10px 15px; - border-radius: 8px; - border: 1px solid rgba(144, 205, 144, 0.2); -} - -.accessibility-item span:first-child { - color: #2d5a27; - font-weight: 500; - font-size: 0.9rem; -} - -.status { - padding: 4px 8px; - border-radius: 6px; - font-size: 0.8rem; - font-weight: 600; -} - -.status.pass { - background: #90cd90; - color: #2d5a27; -} - -.status.fail { - background: #ffcccb; - color: #d32f2f; -} - -/* 加载和错误状态 */ -.loading, -.error { - text-align: center; - padding: 40px 20px; - border-radius: 12px; - margin: 20px 0; -} - -.loading { - background: rgba(144, 205, 144, 0.1); - border: 1px solid rgba(144, 205, 144, 0.3); -} - -.error { - background: rgba(255, 204, 203, 0.3); - border: 1px solid rgba(211, 47, 47, 0.3); -} - -.spinner { - width: 40px; - height: 40px; - border: 4px solid rgba(144, 205, 144, 0.3); - border-top: 4px solid #2d5a27; - border-radius: 50%; - animation: spin 1s linear infinite; - margin: 0 auto 15px; -} - -@keyframes spin { - 0% { transform: rotate(0deg); } - 100% { transform: rotate(360deg); } -} - -.loading p { - color: #2d5a27; - font-weight: 500; -} - -.error p { - color: #d32f2f; - font-weight: 500; -} - -/* 平板端适配 (768px - 1024px) */ -@media (min-width: 768px) and (max-width: 1024px) { - .container { - padding: 30px; - } - - .header h1 { - font-size: 2.5rem; - } - - .main-content { - gap: 35px; - } - - .input-section, - .result-section { - padding: 30px; - } - - .color-preview { - gap: 25px; - } - - .color-box { - width: 100px; - height: 100px; - } - - .color-formats { - grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); - } - - .palette-group { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); - gap: 20px; - } -} - -/* 电脑端适配 (1025px+) */ -@media (min-width: 1025px) { - .container { - padding: 40px; - } - - .header h1 { - font-size: 3rem; - } - - .subtitle { - font-size: 1.1rem; - } - - .main-content { - gap: 40px; - } - - .input-section, - .result-section { - padding: 35px; - } - - .color-preview { - gap: 30px; - padding: 25px; - } - - .color-box { - width: 120px; - height: 120px; - } - - .color-info h3 { - font-size: 1.4rem; - } - - .color-info p { - font-size: 1.2rem; - } - - .color-formats { - grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); - gap: 25px; - } - - .format-group { - padding: 20px; - } - - .palette-group { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 25px; - } - - .button-group { - max-width: 500px; - margin: 25px auto 0; - } - - .btn { - padding: 18px 25px; - font-size: 1.1rem; - } -} - -/* 手机端优化 (最高优先级) */ -@media (max-width: 767px) { - .container { - padding: 15px; - } - - .header { - margin-bottom: 25px; - padding: 15px 0; - } - - .header h1 { - font-size: 1.8rem; - } - - .subtitle { - font-size: 0.9rem; - } - - .main-content { - gap: 25px; - } - - .input-section, - .result-section { - padding: 20px; - border-radius: 12px; - } - - .input-group { - margin-bottom: 18px; - } - - .input-group input, - .input-group select { - padding: 14px 12px; - font-size: 16px; /* 防止iOS缩放 */ - } - - .button-group { - flex-direction: column; - gap: 12px; - margin-top: 20px; - } - - .btn { - padding: 16px 20px; - font-size: 1rem; - border-radius: 8px; - } - - .color-preview { - flex-direction: column; - text-align: center; - gap: 15px; - padding: 15px; - } - - .color-box { - width: 100px; - height: 100px; - margin: 0 auto; - } - - .color-formats { - grid-template-columns: 1fr; - gap: 15px; - } - - .format-group { - padding: 12px; - } - - .format-values { - justify-content: center; - } - - .color-properties { - grid-template-columns: 1fr; - gap: 12px; - } - - .property-item { - flex-direction: column; - gap: 5px; - text-align: center; - padding: 15px; - } - - .palette-group { - gap: 12px; - } - - .palette-item { - padding: 12px; - text-align: center; - } - - .analogous-colors, - .triadic-colors { - justify-content: center; - } - - .analogous-hex, - .triadic-hex { - justify-content: center; - flex-wrap: wrap; - } - - .accessibility-grid { - grid-template-columns: 1fr; - gap: 8px; - } - - .accessibility-item { - flex-direction: column; - gap: 5px; - text-align: center; - padding: 12px; - } - - .loading, - .error { - padding: 30px 15px; - margin: 15px 0; - } - - .spinner { - width: 35px; - height: 35px; - } -} \ No newline at end of file diff --git a/frontend/60sapi/实用功能/随机颜色/返回接口.json b/frontend/60sapi/实用功能/随机颜色/返回接口.json deleted file mode 100644 index 46d731ff..00000000 --- a/frontend/60sapi/实用功能/随机颜色/返回接口.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "code": 200, - "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", - "data": { - "hex": "#A59619", - "name": "红色系", - "rgb": { - "r": 165, - "g": 150, - "b": 25, - "string": "rgb(165, 150, 25)" - }, - "hsl": { - "h": 54, - "s": 74, - "l": 37, - "string": "hsl(54, 74%, 37%)" - }, - "hsv": { - "h": 54, - "s": 85, - "v": 65, - "string": "hsv(54, 85%, 65%)" - }, - "cmyk": { - "c": 0, - "m": 9, - "y": 85, - "k": 35, - "string": "cmyk(0%, 9%, 85%, 35%)" - }, - "lab": { - "l": 62, - "a": -7, - "b": 61, - "string": "lab(62, -7, 61)" - }, - "brightness": 140.235, - "contrast": { - "white": 3.01, - "black": 6.98 - }, - "accessibility": { - "aa_normal": true, - "aa_large": true, - "aaa_normal": false, - "aaa_large": true, - "best_text_color": "#000000" - }, - "complementary": "#1926A4", - "analogous": [ - "#A45019", - "#6CA419" - ], - "triadic": [ - "#19A496", - "#9619A4" - ] - } -} \ No newline at end of file diff --git a/frontend/60sapi/日更资讯/历史上的今天/css/style.css b/frontend/60sapi/日更资讯/历史上的今天/css/style.css deleted file mode 100755 index 93fb1485..00000000 --- a/frontend/60sapi/日更资讯/历史上的今天/css/style.css +++ /dev/null @@ -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); -} \ No newline at end of file diff --git a/frontend/60sapi/日更资讯/历史上的今天/index.html b/frontend/60sapi/日更资讯/历史上的今天/index.html deleted file mode 100755 index 2f941a44..00000000 --- a/frontend/60sapi/日更资讯/历史上的今天/index.html +++ /dev/null @@ -1,83 +0,0 @@ - - - - - - - - 历史上的今天 - 60s API集合 - - - - - - - - - - - - - -
    - -
    -

    📚 历史上的今天

    -

    探索历史,了解今天在历史上发生的重要事件

    -
    - - -
    -
    - 加载中... -
    -
    - - -
    -
    -

    正在加载历史数据...

    -
    - - -
    - - - -
    -

    历史事件

    -
    -
    - -
    -
    -
    -
    - -
    - - - - - - - - \ No newline at end of file diff --git a/frontend/60sapi/日更资讯/历史上的今天/js/script.js b/frontend/60sapi/日更资讯/历史上的今天/js/script.js deleted file mode 100755 index bb0ca469..00000000 --- a/frontend/60sapi/日更资讯/历史上的今天/js/script.js +++ /dev/null @@ -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.api.shumengya.top/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 = ` -
    ${eventType.name}
    -
    ${formatYear(item.year)}
    -
    ${escapeHtml(item.title)}
    -
    ${escapeHtml(item.description)}
    - ${item.link ? `了解更多` : ''} - `; - - 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 = ` -
    -

    😔 加载失败

    -

    ${escapeHtml(message)}

    - -
    - `; - 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 -}; \ No newline at end of file diff --git a/frontend/60sapi/日更资讯/历史上的今天/接口集合.json b/frontend/60sapi/日更资讯/历史上的今天/接口集合.json deleted file mode 100755 index 547b2771..00000000 --- a/frontend/60sapi/日更资讯/历史上的今天/接口集合.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "https://60s.api.shumengya.top" -] diff --git a/frontend/60sapi/日更资讯/历史上的今天/返回接口.json b/frontend/60sapi/日更资讯/历史上的今天/返回接口.json deleted file mode 100755 index 8531e735..00000000 --- a/frontend/60sapi/日更资讯/历史上的今天/返回接口.json +++ /dev/null @@ -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 ,1623-1662)是法国数学家、物理学家、哲学家、散文家。", - "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 III,1746-1792)是瑞典历史上褒贬最多的国王(1771-1792)。阿道夫·弗里德里克国王的儿子和继承者。", - "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 Musgrave,1935年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 Perry,1969年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 Pauling,1901年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°24′~102°23′,北纬31°39′~36°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" - } - ] - } -} \ No newline at end of file diff --git a/frontend/60sapi/日更资讯/必应每日壁纸/css/style.css b/frontend/60sapi/日更资讯/必应每日壁纸/css/style.css deleted file mode 100755 index ac8ca0e5..00000000 --- a/frontend/60sapi/日更资讯/必应每日壁纸/css/style.css +++ /dev/null @@ -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); -} \ No newline at end of file diff --git a/frontend/60sapi/日更资讯/必应每日壁纸/index.html b/frontend/60sapi/日更资讯/必应每日壁纸/index.html deleted file mode 100755 index ac3ecb85..00000000 --- a/frontend/60sapi/日更资讯/必应每日壁纸/index.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - 必应每日壁纸 - - - - - - - - -
    - -
    -

    - 🖼️ - 必应每日壁纸 -

    -

    每天为您呈现精美的必应壁纸,发现世界之美

    -
    - - -
    -
    -

    正在加载今日壁纸...

    -
    - - -
    - -
    -
    - - - - - \ No newline at end of file diff --git a/frontend/60sapi/日更资讯/必应每日壁纸/js/script.js b/frontend/60sapi/日更资讯/必应每日壁纸/js/script.js deleted file mode 100755 index 35ac3881..00000000 --- a/frontend/60sapi/日更资讯/必应每日壁纸/js/script.js +++ /dev/null @@ -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.api.shumengya.top/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 ` -
    -
    -

    ${escapeHtml(info.title)}

    -
    ${info.date}
    - ${info.description ? `
    ${escapeHtml(info.description)}
    ` : ''} -
    - -
    - ${escapeHtml(info.title)} -
    - - -
    - - ${info.copyright ? ` - - ` : ''} - `; -} - -// 绑定图片事件 -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 = ` -
    -

    🖼️ 图片加载失败

    -

    请检查网络连接或稍后重试

    -
    - `; - }); - }); -} - -// 显示/隐藏加载状态 -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 = ` -
    -

    ⚠️ 加载失败

    -

    ${escapeHtml(message)}

    -

    请检查网络连接或稍后重试

    -
    - `; - 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 -}; \ No newline at end of file diff --git a/frontend/60sapi/日更资讯/必应每日壁纸/接口集合.json b/frontend/60sapi/日更资讯/必应每日壁纸/接口集合.json deleted file mode 100755 index 547b2771..00000000 --- a/frontend/60sapi/日更资讯/必应每日壁纸/接口集合.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "https://60s.api.shumengya.top" -] diff --git a/frontend/60sapi/日更资讯/必应每日壁纸/返回接口.json b/frontend/60sapi/日更资讯/必应每日壁纸/返回接口.json deleted file mode 100755 index 2c6a72a4..00000000 --- a/frontend/60sapi/日更资讯/必应每日壁纸/返回接口.json +++ /dev/null @@ -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 - } -} \ No newline at end of file diff --git a/frontend/60sapi/日更资讯/每天60s读懂世界/css/style.css b/frontend/60sapi/日更资讯/每天60s读懂世界/css/style.css deleted file mode 100755 index 9bd66ac6..00000000 --- a/frontend/60sapi/日更资讯/每天60s读懂世界/css/style.css +++ /dev/null @@ -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; - } -} \ No newline at end of file diff --git a/frontend/60sapi/日更资讯/每天60s读懂世界/index.html b/frontend/60sapi/日更资讯/每天60s读懂世界/index.html deleted file mode 100755 index 3240ff17..00000000 --- a/frontend/60sapi/日更资讯/每天60s读懂世界/index.html +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - 每天60秒读懂世界 | 最新资讯 - - - - - - - - - - - - - -
    - -
    -

    📰 每天60秒读懂世界

    -

    获取最新资讯,了解天下大事

    -
    - - - - -
    - -
    -
    -

    正在加载今日资讯...

    -
    -
    -
    - - -
    -

    Made with ❤️ | 数据来源:每天60秒读懂世界API

    -
    - - - - - \ No newline at end of file diff --git a/frontend/60sapi/日更资讯/每天60s读懂世界/js/script.js b/frontend/60sapi/日更资讯/每天60s读懂世界/js/script.js deleted file mode 100755 index a8d48404..00000000 --- a/frontend/60sapi/日更资讯/每天60s读懂世界/js/script.js +++ /dev/null @@ -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.api.shumengya.top/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 = ` -
    -
    -

    正在获取最新资讯...

    -
    - `; - } - } - - showError(message) { - const contentDiv = document.getElementById('content'); - if (contentDiv) { - contentDiv.innerHTML = ` -
    -

    😔 获取失败

    -

    ${message}

    -
    - `; - } - } - - 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 => ` -
    - ${this.escapeHtml(item)} -
    - `).join(''); - } - - // 移除图片显示功能 - - const tipHtml = tip ? ` -
    - 💡 ${this.escapeHtml(tip)} -
    - ` : ''; - - const linkHtml = link ? ` -
    - - 📖 查看原文 - -
    - ` : ''; - - contentDiv.innerHTML = ` -
    -
    -
    ${this.escapeHtml(date)} ${this.escapeHtml(day_of_week || '')}
    - ${lunar_date ? `
    ${this.escapeHtml(lunar_date)}
    ` : ''} -
    -
    - - ${tipHtml} - -
    -

    📰 今日要闻

    - ${newsListHtml} -
    - - ${linkHtml} - -
    -

    数据来源:每天60秒读懂世界

    -

    更新时间:${newsData.api_updated || '未知'}

    -
    - `; - } - - 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(); - } - } -}); \ No newline at end of file diff --git a/frontend/60sapi/日更资讯/每天60s读懂世界/接口集合.json b/frontend/60sapi/日更资讯/每天60s读懂世界/接口集合.json deleted file mode 100755 index 547b2771..00000000 --- a/frontend/60sapi/日更资讯/每天60s读懂世界/接口集合.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "https://60s.api.shumengya.top" -] diff --git a/frontend/60sapi/日更资讯/每天60s读懂世界/返回接口.json b/frontend/60sapi/日更资讯/每天60s读懂世界/返回接口.json deleted file mode 100755 index 7804d62a..00000000 --- a/frontend/60sapi/日更资讯/每天60s读懂世界/返回接口.json +++ /dev/null @@ -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" - } - ] -} \ No newline at end of file diff --git a/frontend/60sapi/日更资讯/每日国际汇率/css/style.css b/frontend/60sapi/日更资讯/每日国际汇率/css/style.css deleted file mode 100755 index 5bb68371..00000000 --- a/frontend/60sapi/日更资讯/每日国际汇率/css/style.css +++ /dev/null @@ -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; -} \ No newline at end of file diff --git a/frontend/60sapi/日更资讯/每日国际汇率/index.html b/frontend/60sapi/日更资讯/每日国际汇率/index.html deleted file mode 100755 index 644740d2..00000000 --- a/frontend/60sapi/日更资讯/每日国际汇率/index.html +++ /dev/null @@ -1,86 +0,0 @@ - - - - - - - - 每日国际汇率 - - - - - - - - -
    - -
    -

    - 💱 - 每日国际汇率 -

    -

    实时获取全球货币汇率信息,助您掌握汇率动态

    -
    - - -
    - - -
    - - -
    - -
    - - -
    -
    -

    正在加载汇率数据...

    -
    - - -
    - -
    -
    -

    基础货币

    -
    更新时间: --
    -
    - - -
    -

    汇率统计

    -
    -
    -
    --
    -
    货币总数
    -
    -
    -
    --
    -
    最后更新
    -
    -
    -
    - - -
    - -
    -
    -
    -
    - - - - - \ No newline at end of file diff --git a/frontend/60sapi/日更资讯/每日国际汇率/js/script.js b/frontend/60sapi/日更资讯/每日国际汇率/js/script.js deleted file mode 100755 index 4f820299..00000000 --- a/frontend/60sapi/日更资讯/每日国际汇率/js/script.js +++ /dev/null @@ -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.api.shumengya.top/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 = ` -
    - ${currencyFlag} - ${rate.currency} -
    -
    ${formatRate(rate.rate)}
    -
    ${currencyName}
    - `; - - 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 = ` -
    -

    ⚠️ 加载失败

    -

    ${escapeHtml(message)}

    -

    请检查网络连接或稍后重试

    -
    - `; - 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 -}; \ No newline at end of file diff --git a/frontend/60sapi/日更资讯/每日国际汇率/接口集合.json b/frontend/60sapi/日更资讯/每日国际汇率/接口集合.json deleted file mode 100755 index 547b2771..00000000 --- a/frontend/60sapi/日更资讯/每日国际汇率/接口集合.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "https://60s.api.shumengya.top" -] diff --git a/frontend/60sapi/日更资讯/每日国际汇率/返回接口.json b/frontend/60sapi/日更资讯/每日国际汇率/返回接口.json deleted file mode 100755 index b376d9c2..00000000 --- a/frontend/60sapi/日更资讯/每日国际汇率/返回接口.json +++ /dev/null @@ -1 +0,0 @@ -{"code":200,"message":"获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841","data":{"base_code":"CNY","updated":"2025/08/19 08:02:31","updated_at":1755561751000,"next_updated":"2025/08/20 08:11:41","next_updated_at":1755648701000,"rates":[{"currency":"CNY","rate":1},{"currency":"AED","rate":0.511124},{"currency":"AFN","rate":9.517171},{"currency":"ALL","rate":11.591448},{"currency":"AMD","rate":53.380737},{"currency":"ANG","rate":0.249125},{"currency":"AOA","rate":130.082117},{"currency":"ARS","rate":180.766035},{"currency":"AUD","rate":0.214039},{"currency":"AWG","rate":0.249125},{"currency":"AZN","rate":0.236907},{"currency":"BAM","rate":0.233194},{"currency":"BBD","rate":0.278352},{"currency":"BDT","rate":16.911823},{"currency":"BGN","rate":0.233216},{"currency":"BHD","rate":0.05233},{"currency":"BIF","rate":416.872549},{"currency":"BMD","rate":0.139176},{"currency":"BND","rate":0.178681},{"currency":"BOB","rate":0.962893},{"currency":"BRL","rate":0.752907},{"currency":"BSD","rate":0.139176},{"currency":"BTN","rate":12.167157},{"currency":"BWP","rate":1.952087},{"currency":"BYN","rate":0.44452},{"currency":"BZD","rate":0.278352},{"currency":"CAD","rate":0.19212},{"currency":"CDF","rate":404.961905},{"currency":"CHF","rate":0.112314},{"currency":"CLP","rate":134.245001},{"currency":"COP","rate":560.180139},{"currency":"CRC","rate":70.415535},{"currency":"CUP","rate":3.340225},{"currency":"CVE","rate":13.146924},{"currency":"CZK","rate":2.918414},{"currency":"DJF","rate":24.734508},{"currency":"DKK","rate":0.889716},{"currency":"DOP","rate":8.582359},{"currency":"DZD","rate":18.079862},{"currency":"EGP","rate":6.734271},{"currency":"ERN","rate":2.087641},{"currency":"ETB","rate":19.722171},{"currency":"EUR","rate":0.119223},{"currency":"FJD","rate":0.314391},{"currency":"FKP","rate":0.102914},{"currency":"FOK","rate":0.889734},{"currency":"GBP","rate":0.102909},{"currency":"GEL","rate":0.375537},{"currency":"GGP","rate":0.102914},{"currency":"GHS","rate":1.578239},{"currency":"GIP","rate":0.102914},{"currency":"GMD","rate":10.138575},{"currency":"GNF","rate":1210.235138},{"currency":"GTQ","rate":1.068254},{"currency":"GYD","rate":29.143934},{"currency":"HKD","rate":1.088795},{"currency":"HNL","rate":3.652528},{"currency":"HRK","rate":0.89834},{"currency":"HTG","rate":18.225889},{"currency":"HUF","rate":47.111579},{"currency":"IDR","rate":2251.38752},{"currency":"ILS","rate":0.471627},{"currency":"IMP","rate":0.102914},{"currency":"INR","rate":12.167163},{"currency":"IQD","rate":182.493562},{"currency":"IRR","rate":5947.331641},{"currency":"ISK","rate":17.059481},{"currency":"JEP","rate":0.102914},{"currency":"JMD","rate":22.284011},{"currency":"JOD","rate":0.098676},{"currency":"JPY","rate":20.560161},{"currency":"KES","rate":18.001838},{"currency":"KGS","rate":12.154697},{"currency":"KHR","rate":559.486842},{"currency":"KID","rate":0.213953},{"currency":"KMF","rate":58.657438},{"currency":"KRW","rate":193.082196},{"currency":"KWD","rate":0.042467},{"currency":"KYD","rate":0.11598},{"currency":"KZT","rate":75.044843},{"currency":"LAK","rate":3020.068103},{"currency":"LBP","rate":12456.256905},{"currency":"LKR","rate":41.92144},{"currency":"LRD","rate":27.931467},{"currency":"LSL","rate":2.453056},{"currency":"LYD","rate":0.753251},{"currency":"MAD","rate":1.256183},{"currency":"MDL","rate":2.318865},{"currency":"MGA","rate":616.246377},{"currency":"MKD","rate":7.330199},{"currency":"MMK","rate":292.821503},{"currency":"MNT","rate":496.284455},{"currency":"MOP","rate":1.121431},{"currency":"MRU","rate":5.575062},{"currency":"MUR","rate":6.322278},{"currency":"MVR","rate":2.152859},{"currency":"MWK","rate":242.759976},{"currency":"MXN","rate":2.615768},{"currency":"MYR","rate":0.587931},{"currency":"MZN","rate":8.897355},{"currency":"NAD","rate":2.453056},{"currency":"NGN","rate":213.548738},{"currency":"NIO","rate":5.126446},{"currency":"NOK","rate":1.418768},{"currency":"NPR","rate":19.467451},{"currency":"NZD","rate":0.234779},{"currency":"OMR","rate":0.053513},{"currency":"PAB","rate":0.139176},{"currency":"PEN","rate":0.494927},{"currency":"PGK","rate":0.582729},{"currency":"PHP","rate":7.93572},{"currency":"PKR","rate":39.46328},{"currency":"PLN","rate":0.506978},{"currency":"PYG","rate":1027.399127},{"currency":"QAR","rate":0.506601},{"currency":"RON","rate":0.603459},{"currency":"RSD","rate":13.970729},{"currency":"RUB","rate":11.172399},{"currency":"RWF","rate":202.11696},{"currency":"SAR","rate":0.52191},{"currency":"SBD","rate":1.166597},{"currency":"SCR","rate":2.048212},{"currency":"SDG","rate":62.256223},{"currency":"SEK","rate":1.330729},{"currency":"SGD","rate":0.178681},{"currency":"SHP","rate":0.102914},{"currency":"SLE","rate":3.233657},{"currency":"SLL","rate":3233.656465},{"currency":"SOS","rate":79.627341},{"currency":"SRD","rate":5.237221},{"currency":"SSP","rate":656.433807},{"currency":"STN","rate":2.921141},{"currency":"SYP","rate":1797.905083},{"currency":"SZL","rate":2.453056},{"currency":"THB","rate":4.522448},{"currency":"TJS","rate":1.304898},{"currency":"TMT","rate":0.487573},{"currency":"TND","rate":0.400111},{"currency":"TOP","rate":0.334775},{"currency":"TRY","rate":5.692494},{"currency":"TTD","rate":0.944407},{"currency":"TVD","rate":0.213953},{"currency":"TWD","rate":4.180337},{"currency":"TZS","rate":362.491953},{"currency":"UAH","rate":5.749996},{"currency":"UGX","rate":495.482314},{"currency":"USD","rate":0.139189},{"currency":"UYU","rate":5.574},{"currency":"UZS","rate":1755.559577},{"currency":"VES","rate":19.06244},{"currency":"VND","rate":3651.953637},{"currency":"VUV","rate":16.614981},{"currency":"WST","rate":0.37355},{"currency":"XAF","rate":78.209917},{"currency":"XCD","rate":0.375775},{"currency":"XCG","rate":0.249125},{"currency":"XDR","rate":0.101791},{"currency":"XOF","rate":78.209917},{"currency":"XPF","rate":14.227984},{"currency":"YER","rate":33.479791},{"currency":"ZAR","rate":2.453082},{"currency":"ZMW","rate":3.244378},{"currency":"ZWL","rate":3.727233}]}} \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/Hacker News 榜单/css/background.css b/frontend/60sapi/热搜榜单/Hacker News 榜单/css/background.css deleted file mode 100755 index b889760c..00000000 --- a/frontend/60sapi/热搜榜单/Hacker News 榜单/css/background.css +++ /dev/null @@ -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); - } -} diff --git a/frontend/60sapi/热搜榜单/Hacker News 榜单/css/style.css b/frontend/60sapi/热搜榜单/Hacker News 榜单/css/style.css deleted file mode 100755 index fe482a48..00000000 --- a/frontend/60sapi/热搜榜单/Hacker News 榜单/css/style.css +++ /dev/null @@ -1,863 +0,0 @@ -/* 背景样式 */ -.background-container { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: -1; - overflow: hidden; - background-color: #f8f9fa; -} - -.modern-gradient { - position: absolute; - top: -50%; - left: -50%; - width: 200%; - height: 200%; - background: linear-gradient( - 135deg, - rgba(64, 169, 255, 0.4) 0%, - rgba(120, 192, 255, 0.3) 25%, - rgba(255, 175, 64, 0.2) 50%, - rgba(255, 140, 50, 0.3) 75%, - rgba(255, 122, 69, 0.4) 100% - ); - animation: gradient-flow 20s ease-in-out infinite; - border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%; -} - -.modern-gradient::before { - content: ''; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: radial-gradient( - circle at 30% 70%, - rgba(64, 169, 255, 0.5) 0%, - transparent 50% - ), radial-gradient( - circle at 70% 30%, - rgba(255, 140, 50, 0.4) 0%, - transparent 50% - ); - animation: pulse-effect 15s ease-in-out infinite alternate; - border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%; -} - -@keyframes gradient-flow { - 0%, 100% { - transform: rotate(0deg) scale(1); - opacity: 0.8; - } - 25% { - transform: rotate(90deg) scale(1.1); - opacity: 0.6; - } - 50% { - transform: rotate(180deg) scale(0.9); - opacity: 0.9; - } - 75% { - transform: rotate(270deg) scale(1.05); - opacity: 0.7; - } -} - -@keyframes pulse-effect { - 0% { - transform: scale(1) rotate(0deg); - opacity: 0.5; - } - 50% { - transform: scale(1.2) rotate(180deg); - opacity: 0.8; - } - 100% { - transform: scale(1) rotate(360deg); - opacity: 0.6; - } -} - -/* 主样式 */ -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -body { - font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif; - color: #333; - background-color: #f8f9fa; - position: relative; - min-height: 100vh; -} - -.container { - max-width: 800px; - margin: 0 auto; - padding: 24px; - position: relative; - z-index: 1; - background-color: rgba(255, 255, 255, 0.85); - border-radius: 16px; - box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08); - backdrop-filter: blur(10px); -} - -header, .header { - text-align: center; - margin-bottom: 28px; - padding-bottom: 20px; - border-bottom: 1px solid rgba(0, 0, 0, 0.06); -} - -.header-icon { - font-size: 3rem; - margin-bottom: 10px; - display: block; -} - -header h1, .title { - background: linear-gradient(135deg, #4096ff, #ff7a45); - -webkit-background-clip: text; - background-clip: text; - color: transparent; - margin-bottom: 14px; - font-size: 2.4rem; - font-weight: 700; - letter-spacing: -0.5px; -} - -.subtitle { - color: #666; - font-size: 1.1rem; - margin-bottom: 20px; - font-weight: 400; -} - -.tab-container { - display: flex; - justify-content: center; - gap: 12px; - margin-bottom: 20px; - flex-wrap: wrap; -} - -.tab-btn { - background: linear-gradient(135deg, #f0f0f0, #e8e8e8); - border: none; - padding: 12px 20px; - border-radius: 25px; - cursor: pointer; - font-size: 0.95rem; - font-weight: 500; - color: #666; - transition: all 0.3s ease; - display: flex; - align-items: center; - gap: 6px; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); -} - -.tab-btn:hover { - transform: translateY(-2px); - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); -} - -.tab-btn.active { - background: linear-gradient(135deg, #4096ff, #40a9ff); - color: white; - box-shadow: 0 4px 16px rgba(64, 150, 255, 0.3); -} - -.tab-icon { - font-size: 1.1rem; -} - -.refresh-btn { - background: linear-gradient(135deg, #52c41a, #73d13d); - border: none; - padding: 12px 24px; - border-radius: 25px; - color: white; - cursor: pointer; - font-size: 0.95rem; - font-weight: 500; - margin-top: 15px; - transition: all 0.3s ease; - display: inline-flex; - align-items: center; - gap: 8px; - box-shadow: 0 4px 12px rgba(82, 196, 26, 0.3); -} - -.refresh-btn:hover { - transform: translateY(-2px); - box-shadow: 0 6px 16px rgba(82, 196, 26, 0.4); -} - -.btn-icon { - font-size: 1.1rem; -} - -.time-icon { - margin-right: 6px; -} - -.update-time { - color: #666; - font-size: 0.9rem; - background-color: rgba(0, 0, 0, 0.03); - padding: 8px 16px; - border-radius: 24px; - display: inline-block; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04); -} - -.hot-list { - list-style: none; -} - -.hot-item { - padding: 20px; - margin-bottom: 16px; - border-radius: 12px; - background-color: white; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.04); - transition: all 0.3s ease; - display: flex; - align-items: center; - border: 1px solid rgba(0, 0, 0, 0.03); -} - -.hot-item:hover { - transform: translateY(-3px); - box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08); - border-color: rgba(64, 169, 255, 0.3); -} - -.hot-rank { - font-size: 1.2rem; - font-weight: bold; - color: #4096ff; - margin-right: 18px; - min-width: 38px; - text-align: center; - background-color: rgba(64, 169, 255, 0.1); - border-radius: 50%; - width: 38px; - height: 38px; - display: flex; - align-items: center; - justify-content: center; -} - -.hot-rank.top-1 { - background: linear-gradient(135deg, #ff4d4f, #ff7a45); - color: white; -} - -.hot-rank.top-2 { - background: linear-gradient(135deg, #ff7a45, #ffa940); - color: white; -} - -.hot-rank.top-3 { - background: linear-gradient(135deg, #ffa940, #ffec3d); - color: white; -} - -.hot-content { - flex: 1; -} - -.hot-title { - font-size: 1.15rem; - margin-bottom: 8px; - color: #333; - text-decoration: none; - display: block; - line-height: 1.5; - font-weight: 500; - transition: color 0.2s ease; -} - -.hot-title:hover { - color: #4096ff; - text-decoration: none; -} - -.loading { - text-align: center; - padding: 40px; - color: #666; - font-size: 1.1rem; - display: none; -} - -.loading-content { - display: flex; - flex-direction: column; - align-items: center; - gap: 20px; -} - -.rainbow-spinner { - width: 50px; - height: 50px; - border: 4px solid transparent; - border-top: 4px solid #4096ff; - border-radius: 50%; - animation: spin 1s linear infinite; - background: linear-gradient(45deg, #ff6b6b, #4ecdc4, #45b7d1, #96ceb4, #feca57, #ff9ff3, #54a0ff, #5f27cd); - background-size: 400% 400%; - animation: spin 1s linear infinite, rainbowGradient 3s ease infinite; -} - -@keyframes spin { - 0% { transform: rotate(0deg); } - 100% { transform: rotate(360deg); } -} - -.loading-text { - display: flex; - flex-direction: column; - align-items: center; - gap: 10px; -} - -.loading-emoji { - font-size: 2rem; - animation: bounce 1.5s ease-in-out infinite; -} - -@keyframes bounce { - 0%, 20%, 50%, 80%, 100% { - transform: translateY(0); - } - 40% { - transform: translateY(-10px); - } - 60% { - transform: translateY(-5px); - } -} - -.loading-dots { - display: flex; - gap: 4px; -} - -.loading-dots span { - width: 8px; - height: 8px; - background: #4096ff; - border-radius: 50%; - animation: loadingDots 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; } -.loading-dots span:nth-child(3) { animation-delay: 0s; } - -@keyframes loadingDots { - 0%, 80%, 100% { - transform: scale(0); - } - 40% { - transform: scale(1); - } -} - -.news-list { - margin-top: 20px; -} - -/* 新闻项目卡片 - 移动端优先设计 */ -.news-item { - background: white; - border-radius: 16px; - padding: 16px; - margin-bottom: 12px; - box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06); - transition: all 0.3s ease; - border: 1px solid rgba(0, 0, 0, 0.05); - display: flex; - gap: 12px; - position: relative; - overflow: hidden; -} - -.news-item:hover { - transform: translateY(-2px); - box-shadow: 0 6px 20px rgba(0, 0, 0, 0.1); - border-color: rgba(64, 169, 255, 0.2); -} - -/* 排名容器 */ -.news-rank-container { - flex-shrink: 0; - display: flex; - align-items: flex-start; - padding-top: 2px; -} - -.news-rank { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - width: 48px; - height: 48px; - border-radius: 12px; - background: linear-gradient(135deg, #f0f0f0, #e8e8e8); - color: #666; - font-weight: 600; - position: relative; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); -} - -.news-rank.rank-1 { - background: linear-gradient(135deg, #ff4d4f, #ff7a45); - color: white; - box-shadow: 0 4px 12px rgba(255, 77, 79, 0.3); -} - -.news-rank.rank-2 { - background: linear-gradient(135deg, #ff7a45, #ffa940); - color: white; - box-shadow: 0 4px 12px rgba(255, 122, 69, 0.3); -} - -.news-rank.rank-3 { - background: linear-gradient(135deg, #ffa940, #ffec3d); - color: #333; - box-shadow: 0 4px 12px rgba(255, 169, 64, 0.3); -} - -.rank-number { - font-size: 0.9rem; - font-weight: 700; - line-height: 1; -} - -.rank-emoji { - font-size: 0.7rem; - line-height: 1; - margin-top: 1px; -} - -/* 内容包装器 */ -.news-content-wrapper { - flex: 1; - min-width: 0; - display: flex; - flex-direction: column; - gap: 8px; -} - -/* 标题 */ -.news-title { - font-size: 1rem; - font-weight: 600; - color: #333; - line-height: 1.4; - margin: 0; - display: -webkit-box; - -webkit-line-clamp: 2; - -webkit-box-orient: vertical; - overflow: hidden; - text-overflow: ellipsis; - cursor: pointer; - transition: color 0.2s ease; -} - -.news-title:hover { - color: #4096ff; -} - -/* 元信息行 */ -.news-meta-row { - display: flex; - justify-content: space-between; - align-items: center; - gap: 12px; - flex-wrap: wrap; -} - -.news-author, .news-time { - display: flex; - align-items: center; - gap: 4px; - color: #666; - font-size: 0.8rem; - flex: 1; - min-width: 0; -} - -.meta-icon { - font-size: 0.9rem; - flex-shrink: 0; -} - -.meta-text { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -/* 统计信息行 */ -.news-stats-row { - display: flex; - justify-content: space-between; - align-items: center; - gap: 12px; - margin-top: 4px; -} - -.news-score { - display: flex; - align-items: center; - gap: 4px; - background: linear-gradient(135deg, #ff6b6b, #4ecdc4); - color: white; - padding: 4px 10px; - border-radius: 12px; - font-size: 0.75rem; - font-weight: 600; - box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); -} - -.heat-level { - font-size: 0.8rem; -} - -.score-text { - font-size: 0.75rem; -} - -.news-link { - display: flex; - align-items: center; - gap: 4px; - background: linear-gradient(135deg, #4096ff, #40a9ff); - color: white; - text-decoration: none; - padding: 6px 12px; - border-radius: 12px; - font-size: 0.75rem; - font-weight: 600; - transition: all 0.3s ease; - box-shadow: 0 2px 6px rgba(64, 150, 255, 0.3); - flex-shrink: 0; -} - -.news-link:hover { - transform: translateY(-1px); - box-shadow: 0 4px 10px rgba(64, 150, 255, 0.4); - text-decoration: none; - color: white; -} - -.link-icon { - font-size: 0.8rem; -} - -.link-text { - font-size: 0.75rem; -} - -.error-message { - text-align: center; - padding: 40px; - background: white; - border-radius: 12px; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.04); -} - -.error-content { - display: flex; - flex-direction: column; - align-items: center; - gap: 16px; -} - -.error-icon { - font-size: 3rem; -} - -.error-content h3 { - color: #ff4d4f; - margin: 0; - font-size: 1.3rem; -} - -.error-content p { - color: #666; - margin: 0; - font-size: 1rem; -} - -.retry-btn { - background: linear-gradient(135deg, #ff4d4f, #ff7a45); - border: none; - padding: 12px 24px; - border-radius: 25px; - color: white; - cursor: pointer; - font-size: 0.95rem; - font-weight: 500; - transition: all 0.3s ease; - display: inline-flex; - align-items: center; - gap: 8px; - box-shadow: 0 4px 12px rgba(255, 77, 79, 0.3); -} - -.retry-btn:hover { - transform: translateY(-2px); - box-shadow: 0 6px 16px rgba(255, 77, 79, 0.4); -} - -footer { - text-align: center; - margin-top: 30px; - padding-top: 20px; - border-top: 1px solid rgba(0, 0, 0, 0.06); - color: #666; - font-size: 0.9rem; -} - -/* 响应式设计 - 移动端优化 */ -@media (max-width: 1024px) and (min-width: 768px) { - .container { - max-width: 90%; - padding: 20px; - } - - header h1 { - font-size: 2.2rem; - } - - .hot-item { - padding: 18px; - } - - .hot-title { - font-size: 1.1rem; - } -} - -@media (max-width: 768px) { - body { - background-color: #f8f9fa; - } - - .container { - max-width: 95%; - margin: 12px auto; - padding: 8px; - border-radius: 12px; - } - - header, .header { - margin-bottom: 20px; - padding: 12px 0 16px 0; - } - - header h1, .title { - font-size: 1.6rem; - margin-bottom: 10px; - } - - .subtitle { - font-size: 0.85rem; - } - - .tab-container { - gap: 8px; - margin: 16px 0; - } - - .tab-btn { - padding: 8px 12px; - font-size: 0.8rem; - min-width: auto; - } - - .refresh-btn { - padding: 8px 10px; - font-size: 0.8rem; - } - - .update-time { - font-size: 0.85rem; - padding: 6px 12px; - } - - .hot-item { - padding: 16px; - margin-bottom: 12px; - border-radius: 10px; - flex-direction: row; - align-items: flex-start; - } - - .hot-rank { - font-size: 1.1rem; - margin-right: 14px; - min-width: 32px; - width: 32px; - height: 32px; - margin-top: 2px; - } - - .hot-title { - font-size: 1rem; - line-height: 1.5; - margin-bottom: 6px; - } - - .news-item { - padding: 12px; - margin-bottom: 10px; - gap: 10px; - } - - .news-rank { - width: 40px; - height: 40px; - } - - .rank-number { - font-size: 0.8rem; - } - - .rank-emoji { - font-size: 0.6rem; - } - - .news-title { - font-size: 0.9rem; - line-height: 1.3; - } - - .news-meta-row { - gap: 8px; - } - - .news-author, .news-time { - font-size: 0.75rem; - } - - .news-score { - padding: 3px 8px; - font-size: 0.7rem; - } - - .news-link { - padding: 5px 10px; - font-size: 0.7rem; - } - - .link-text { - font-size: 0.7rem; - } - - footer { - margin-top: 24px; - padding-top: 16px; - font-size: 0.85rem; - } -} - -@media (max-width: 480px) { - .container { - margin: 8px auto; - padding: 6px; - } - - header h1, .title { - font-size: 1.6rem; - } - - .hot-item { - padding: 14px; - margin-bottom: 10px; - } - - .hot-rank { - font-size: 1rem; - margin-right: 12px; - min-width: 30px; - width: 30px; - height: 30px; - } - - .hot-title { - font-size: 0.95rem; - } - - .news-item { - padding: 10px; - gap: 8px; - } - - .news-rank { - width: 36px; - height: 36px; - } - - .rank-number { - font-size: 0.75rem; - } - - .news-title { - font-size: 0.85rem; - } - - .news-meta-row { - flex-direction: column; - align-items: flex-start; - gap: 6px; - } - - .news-stats-row { - gap: 8px; - } - - .news-author, .news-time { - font-size: 0.7rem; - } - - .news-score { - font-size: 0.65rem; - } - - .news-link { - font-size: 0.65rem; - padding: 4px 8px; - } -} - -/* 减少动画以节省电池 */ -@media (prefers-reduced-motion: reduce) { - .modern-gradient, - .modern-gradient::before { - animation: none; - } - - .modern-gradient { - background: linear-gradient( - 135deg, - rgba(64, 169, 255, 0.3) 0%, - rgba(255, 175, 64, 0.2) 50%, - rgba(255, 122, 69, 0.25) 100% - ); - } -} \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/Hacker News 榜单/index.html b/frontend/60sapi/热搜榜单/Hacker News 榜单/index.html deleted file mode 100755 index 765583af..00000000 --- a/frontend/60sapi/热搜榜单/Hacker News 榜单/index.html +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - 🔥 HackerNews 热门榜单 - - - - -
    -
    -
    🌈
    -

    🔥 HackerNews 热门榜单 💻

    -

    全球技术社区 · 实时热门话题

    - -
    - - - -
    - -
    - - 加载中... -
    - - -
    - -
    -
    -
    -
    - 🚀 -

    正在获取最新榜单...

    -
    - - - -
    -
    -
    -
    - -
    - -
    - - -
    - - - - diff --git a/frontend/60sapi/热搜榜单/Hacker News 榜单/js/script.js b/frontend/60sapi/热搜榜单/Hacker News 榜单/js/script.js deleted file mode 100755 index b9b4caa5..00000000 --- a/frontend/60sapi/热搜榜单/Hacker News 榜单/js/script.js +++ /dev/null @@ -1,349 +0,0 @@ -// API接口列表 -const API_ENDPOINTS = [ - "https://60s.api.shumengya.top", -]; - -// 当前使用的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 <= 3 ? `news-rank rank-${rank}` : '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 = '🥉'; - - // 根据评分添加热度指示 - let heatLevel = ''; - if (item.score >= 1000) heatLevel = '🔥🔥🔥'; - else if (item.score >= 500) heatLevel = '🔥🔥'; - else if (item.score >= 100) heatLevel = '🔥'; - else heatLevel = '💫'; - - newsItem.innerHTML = ` -
    -
    - ${rank} - ${rankEmoji} -
    -
    -
    -

    ${escapeHtml(item.title)}

    -
    -
    - 👤 - ${escapeHtml(item.author)} -
    -
    - 🕒 - ${formattedTime} -
    -
    -
    -
    - ${heatLevel} - ${formattedScore} 分 -
    - - 🚀 - 阅读全文 - -
    -
    - `; - - 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(); - } - } -}); diff --git a/frontend/60sapi/热搜榜单/Hacker News 榜单/接口集合.json b/frontend/60sapi/热搜榜单/Hacker News 榜单/接口集合.json deleted file mode 100755 index 547b2771..00000000 --- a/frontend/60sapi/热搜榜单/Hacker News 榜单/接口集合.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "https://60s.api.shumengya.top" -] diff --git a/frontend/60sapi/热搜榜单/Hacker News 榜单/返回接口.json b/frontend/60sapi/热搜榜单/Hacker News 榜单/返回接口.json deleted file mode 100755 index 0008f691..00000000 --- a/frontend/60sapi/热搜榜单/Hacker News 榜单/返回接口.json +++ /dev/null @@ -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 - } - ] -} \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/css/background.css b/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/css/background.css deleted file mode 100755 index 7a26d1e7..00000000 --- a/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/css/background.css +++ /dev/null @@ -1,203 +0,0 @@ -.background-container { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: -1; - overflow: hidden; - background-color: #f0f7ff; -} - -/* 太阳元素 */ -.sun { - position: absolute; - top: 50px; - right: 35%; - width: 60px; - height: 60px; - background: radial-gradient(circle, #ffeb3b 30%, #ff9800 70%); - border-radius: 50%; - box-shadow: 0 0 40px rgba(255, 152, 0, 0.6); - z-index: 0; - animation: sun-pulse 8s ease-in-out infinite; -} - -/* 蓝色云元素 */ -.cloud { - position: absolute; - background: rgba(135, 206, 250, 0.8); - border-radius: 50px; - box-shadow: 0 8px 15px rgba(0, 0, 0, 0.1); - z-index: -1; -} - -.cloud-1 { - top: 120px; - left: -150px; - width: 120px; - height: 40px; - animation: cloud-float 15s linear infinite; -} - -.cloud-2 { - top: 180px; - right: -150px; - width: 160px; - height: 50px; - animation: cloud-float 20s linear infinite reverse; -} - -.cloud-3 { - top: 60px; - left: -100px; - width: 100px; - height: 35px; - animation: cloud-float 12s linear infinite; -} - -/* 云朵的伪元素,创建更自然的形状 */ -.cloud::before, -.cloud::after { - content: ''; - position: absolute; - background: rgba(135, 206, 250, 0.8); - border-radius: 50%; -} - -.cloud::before { - width: 50px; - height: 50px; - top: -20px; - left: 15px; -} - -.cloud::after { - width: 60px; - height: 60px; - top: -30px; - right: 15px; -} - -@keyframes sun-pulse { - 0%, 100% { - transform: scale(1); - box-shadow: 0 0 40px rgba(255, 152, 0, 0.6); - } - 50% { - transform: scale(1.1); - box-shadow: 0 0 60px rgba(255, 152, 0, 0.8); - } -} - -@keyframes cloud-float { - 0% { - transform: translateX(-150px); - } - 100% { - transform: translateX(calc(100vw + 150px)); - } -} - -.modern-gradient { - position: absolute; - top: -50%; - left: -50%; - width: 200%; - height: 200%; - background: linear-gradient( - 135deg, - rgba(24, 144, 255, 0.6) 0%, - rgba(64, 169, 255, 0.5) 20%, - rgba(135, 208, 255, 0.4) 40%, - rgba(255, 175, 64, 0.4) 60%, - rgba(255, 122, 69, 0.5) 80%, - rgba(245, 85, 65, 0.6) 100% - ); - animation: gradient-flow 25s ease-in-out infinite; - border-radius: 40% 60% 60% 40% / 40% 40% 60% 60%; - filter: blur(30px); -} - -.modern-gradient::before { - content: ''; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: radial-gradient( - circle at 25% 65%, - rgba(24, 144, 255, 0.6) 0%, - transparent 60% - ), radial-gradient( - circle at 75% 35%, - rgba(245, 85, 65, 0.5) 0%, - transparent 60% - ); - animation: pulse-effect 18s ease-in-out infinite alternate; - border-radius: 40% 60% 60% 40% / 40% 40% 60% 60%; - filter: blur(20px); -} - -@keyframes gradient-flow { - 0%, 100% { - transform: rotate(0deg) scale(1); - opacity: 0.8; - } - 25% { - transform: rotate(90deg) scale(1.1); - opacity: 0.6; - } - 50% { - transform: rotate(180deg) scale(0.9); - opacity: 0.9; - } - 75% { - transform: rotate(270deg) scale(1.05); - opacity: 0.7; - } -} - -@keyframes pulse-effect { - 0% { - transform: scale(1) rotate(0deg); - opacity: 0.5; - } - 50% { - transform: scale(1.2) rotate(180deg); - opacity: 0.8; - } - 100% { - transform: scale(1) rotate(360deg); - opacity: 0.6; - } -} - -/* 手机端背景优化 */ -@media (max-width: 768px) { - .modern-gradient { - animation-duration: 25s; - } - - .modern-gradient::before { - animation-duration: 18s; - } -} - -/* 减少动画以节省电池 */ -@media (prefers-reduced-motion: reduce) { - .modern-gradient, - .modern-gradient::before { - animation: none; - } - - .modern-gradient { - background: linear-gradient( - 135deg, - rgba(64, 169, 255, 0.3) 0%, - rgba(255, 175, 64, 0.2) 50%, - rgba(255, 122, 69, 0.25) 100% - ); - } -} \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/css/style.css b/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/css/style.css deleted file mode 100755 index d172b7e7..00000000 --- a/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/css/style.css +++ /dev/null @@ -1,352 +0,0 @@ -/* 背景样式 */ -.background-container { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: -1; - overflow: hidden; - background-color: #f8f9fa; -} - -.modern-gradient { - position: absolute; - top: -50%; - left: -50%; - width: 200%; - height: 200%; - background: linear-gradient( - 135deg, - rgba(64, 169, 255, 0.4) 0%, - rgba(120, 192, 255, 0.3) 25%, - rgba(255, 175, 64, 0.2) 50%, - rgba(255, 140, 50, 0.3) 75%, - rgba(255, 122, 69, 0.4) 100% - ); - animation: gradient-flow 20s ease-in-out infinite; - border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%; -} - -.modern-gradient::before { - content: ''; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: radial-gradient( - circle at 30% 70%, - rgba(64, 169, 255, 0.5) 0%, - transparent 50% - ), radial-gradient( - circle at 70% 30%, - rgba(255, 140, 50, 0.4) 0%, - transparent 50% - ); - animation: pulse-effect 15s ease-in-out infinite alternate; - border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%; -} - -@keyframes gradient-flow { - 0%, 100% { - transform: rotate(0deg) scale(1); - opacity: 0.8; - } - 25% { - transform: rotate(90deg) scale(1.1); - opacity: 0.6; - } - 50% { - transform: rotate(180deg) scale(0.9); - opacity: 0.9; - } - 75% { - transform: rotate(270deg) scale(1.05); - opacity: 0.7; - } -} - -@keyframes pulse-effect { - 0% { - transform: scale(1) rotate(0deg); - opacity: 0.5; - } - 50% { - transform: scale(1.2) rotate(180deg); - opacity: 0.8; - } - 100% { - transform: scale(1) rotate(360deg); - opacity: 0.6; - } -} - -/* 主样式 */ -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -body { - font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif; - color: #333; - background-color: #f0f7ff; - position: relative; - min-height: 100vh; -} - -.container { - max-width: 800px; - margin: 20px auto; - padding: 28px; - position: relative; - z-index: 1; - background-color: rgba(255, 255, 255, 0.8); - border-radius: 24px; - box-shadow: 0 15px 40px rgba(0, 0, 0, 0.1); - backdrop-filter: blur(15px); - border: 1px solid rgba(255, 255, 255, 0.6); -} - -header { - text-align: center; - margin-bottom: 32px; - padding-bottom: 24px; - border-bottom: 1px solid rgba(0, 0, 0, 0.04); -} - -header h1 { - background: linear-gradient(135deg, #1890ff, #ff7a45); - -webkit-background-clip: text; - background-clip: text; - color: transparent; - margin-bottom: 16px; - font-size: 2.6rem; - font-weight: 800; - letter-spacing: -0.5px; - text-shadow: 0 2px 10px rgba(0, 0, 0, 0.05); -} - -.update-time { - color: #666; - font-size: 0.9rem; - background-color: rgba(255, 255, 255, 0.7); - padding: 10px 20px; - border-radius: 30px; - display: inline-block; - box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05); - border: 1px solid rgba(255, 255, 255, 0.8); -} - -.hot-list { - list-style: none; -} - -.hot-item { - padding: 22px; - margin-bottom: 20px; - border-radius: 16px; - background-color: white; - box-shadow: 0 8px 20px rgba(0, 0, 0, 0.06); - transition: all 0.3s ease; - display: flex; - align-items: center; - border: 1px solid rgba(255, 255, 255, 0.8); -} - -.hot-item:hover { - transform: translateY(-3px); - box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08); - border-color: rgba(64, 169, 255, 0.3); -} - -.hot-rank { - font-size: 1.2rem; - font-weight: bold; - color: #4096ff; - margin-right: 18px; - min-width: 38px; - text-align: center; - background-color: rgba(64, 169, 255, 0.1); - border-radius: 50%; - width: 38px; - height: 38px; - display: flex; - align-items: center; - justify-content: center; -} - -.hot-rank.top-1 { - background: linear-gradient(135deg, #ff4d4f, #ff7a45); - color: white; -} - -.hot-rank.top-2 { - background: linear-gradient(135deg, #ff7a45, #ffa940); - color: white; -} - -.hot-rank.top-3 { - background: linear-gradient(135deg, #ffa940, #ffec3d); - color: white; -} - -.hot-content { - flex: 1; -} - -.hot-title { - font-size: 1.15rem; - margin-bottom: 8px; - color: #333; - text-decoration: none; - display: block; - line-height: 1.5; - font-weight: 500; - transition: color 0.2s ease; -} - -.hot-title:hover { - color: #4096ff; - text-decoration: none; -} - -.loading { - text-align: center; - padding: 40px; - color: #666; - font-size: 1.1rem; -} - -footer { - text-align: center; - margin-top: 30px; - padding-top: 20px; - border-top: 1px solid rgba(0, 0, 0, 0.06); - color: #666; - font-size: 0.9rem; -} - -/* 响应式设计 */ -@media (max-width: 1024px) and (min-width: 768px) { - .container { - max-width: 90%; - padding: 20px; - } - - header h1 { - font-size: 2.2rem; - } - - .hot-item { - padding: 18px; - } - - .hot-title { - font-size: 1.1rem; - } -} - -@media (max-width: 768px) { - body { - background-color: #f8f9fa; - } - - .container { - max-width: 95%; - margin: 12px auto; - padding: 16px; - border-radius: 12px; - } - - header { - margin-bottom: 20px; - padding-bottom: 16px; - } - - header h1 { - font-size: 1.8rem; - margin-bottom: 10px; - } - - .update-time { - font-size: 0.85rem; - padding: 6px 12px; - } - - .hot-item { - padding: 16px; - margin-bottom: 12px; - border-radius: 10px; - flex-direction: row; - align-items: flex-start; - } - - .hot-rank { - font-size: 1.1rem; - margin-right: 14px; - min-width: 32px; - width: 32px; - height: 32px; - margin-top: 2px; - } - - .hot-title { - font-size: 1rem; - line-height: 1.5; - margin-bottom: 6px; - } - - footer { - margin-top: 24px; - padding-top: 16px; - font-size: 0.85rem; - } -} - -@media (max-width: 480px) { - .container { - margin: 8px auto; - padding: 14px; - } - - header h1 { - font-size: 1.6rem; - } - - .hot-item { - padding: 14px; - margin-bottom: 10px; - } - - .hot-rank { - font-size: 1rem; - margin-right: 12px; - min-width: 30px; - width: 30px; - height: 30px; - } - - .hot-title { - font-size: 0.95rem; - } -} - -/* 减少动画以节省电池 */ -@media (prefers-reduced-motion: reduce) { - .modern-gradient, - .modern-gradient::before { - animation: none; - } - - .modern-gradient { - background: linear-gradient( - 135deg, - rgba(64, 169, 255, 0.3) 0%, - rgba(255, 175, 64, 0.2) 50%, - rgba(255, 122, 69, 0.25) 100% - ); - } -} \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/index.html b/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/index.html deleted file mode 100755 index 5c58a175..00000000 --- a/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/index.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - 哔哩哔哩热搜榜 - - - - -
    -
    -
    - -
    -
    -

    哔哩哔哩热搜榜

    -
    -
    - -
    -
    -
    加载中...
    -
    -
    - -
    -

    数据来源于哔哩哔哩热搜榜

    -
    -
    - - - - \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/js/main.js b/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/js/main.js deleted file mode 100755 index 7de0e4b9..00000000 --- a/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/js/main.js +++ /dev/null @@ -1,130 +0,0 @@ -// API接口列表 -const API_ENDPOINTS = [ - "https://60s.api.shumengya.top/v2/bili" -]; - -// 当前使用的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 = ` -
    ${index + 1}
    - - `; - - hotListElement.appendChild(hotItem); - }); - - // 更新时间 - updateTimeElement.textContent = `更新时间:${formatDate(new Date())}`; -} - -// 显示加载状态 -function showLoading() { - hotListElement.innerHTML = '
    加载中...
    '; -} - -// 显示错误状态 -function showError(message) { - hotListElement.innerHTML = `
    ${message}
    `; -} - -// 获取哔哩哔哩热搜数据 -async function fetchBiliHotList() { - showLoading(); - - try { - const response = await fetch(API_ENDPOINTS[currentApiIndex]); - - if (!response.ok) { - throw new Error(`HTTP ${response.status}: ${response.statusText}`); - } - - const result = await response.json(); - - if (result.code === 200 && result.data && Array.isArray(result.data)) { - if (result.data.length > 0) { - renderHotList(result.data); - } else { - showError('暂无热搜数据'); - } - } else { - throw new Error('数据格式错误或无数据'); - } - } catch (error) { - console.error('获取数据失败:', error); - - // 尝试切换到下一个API - const nextApiIndex = (currentApiIndex + 1) % API_ENDPOINTS.length; - - if (nextApiIndex !== 0) { - // 还有其他API可以尝试 - currentApiIndex = nextApiIndex; - showError('获取数据失败,正在尝试其他接口...'); - - // 延迟后重试 - setTimeout(fetchBiliHotList, 2000); - } else { - // 所有API都尝试过了 - currentApiIndex = 0; - showError('所有接口都无法访问,请稍后再试'); - } - } -} - -// 手动刷新数据 -function refreshData() { - currentApiIndex = 0; // 重置API索引 - fetchBiliHotList(); -} - -// 页面加载完成后获取数据 -document.addEventListener('DOMContentLoaded', () => { - fetchBiliHotList(); - - // 每隔5分钟刷新一次数据 - setInterval(fetchBiliHotList, 5 * 60 * 1000); - - // 添加键盘快捷键支持(按R键刷新) - document.addEventListener('keydown', (event) => { - if (event.key === 'r' || event.key === 'R') { - event.preventDefault(); - refreshData(); - } - }); -}); - -// 页面可见性变化时的处理 -document.addEventListener('visibilitychange', () => { - if (!document.hidden) { - // 页面重新可见时刷新数据 - refreshData(); - } -}); \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/接口集合.json b/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/接口集合.json deleted file mode 100755 index 084d6336..00000000 --- a/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/接口集合.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "https://60s.api.shumengya.top" -] diff --git a/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/返回接口.json b/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/返回接口.json deleted file mode 100755 index e377277d..00000000 --- a/frontend/60sapi/热搜榜单/哔哩哔哩热搜榜/返回接口.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "code": 200, - "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", - "data": [ - { - "title": "18次阅兵76年逆袭路", - "link": "https://search.bilibili.com/all?keyword=18%E6%AC%A1%E9%98%85%E5%85%B576%E5%B9%B4%E9%80%86%E8%A2%AD%E8%B7%AF" - }, - { - "title": "80年前的今天日本签署投降书", - "link": "https://search.bilibili.com/all?keyword=80%E5%B9%B4%E5%89%8D%E7%9A%84%E4%BB%8A%E5%A4%A9%E6%97%A5%E6%9C%AC%E7%AD%BE%E7%BD%B2%E6%8A%95%E9%99%8D%E4%B9%A6" - }, - { - "title": "九三阅兵具体安排公布", - "link": "https://search.bilibili.com/all?keyword=%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" - } - ] -} \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/头条热搜榜/css/background.css b/frontend/60sapi/热搜榜单/头条热搜榜/css/background.css deleted file mode 100755 index d3c2c6e3..00000000 --- a/frontend/60sapi/热搜榜单/头条热搜榜/css/background.css +++ /dev/null @@ -1,107 +0,0 @@ -.background-container { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: -1; - overflow: hidden; -} - -.green-gradient { - position: absolute; - top: -50%; - left: -50%; - width: 200%; - height: 200%; - background: linear-gradient( - 135deg, - rgba(240, 20, 20, 0.3) 0%, - rgba(255, 60, 60, 0.2) 25%, - rgba(255, 100, 100, 0.1) 50%, - rgba(255, 150, 150, 0.2) 75%, - rgba(240, 20, 20, 0.3) 100% - ); - animation: green-flow 20s ease-in-out infinite; -} - -.green-gradient::before { - content: ''; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: radial-gradient( - circle at 30% 70%, - rgba(255, 45, 45, 0.4) 0%, - transparent 50% - ), radial-gradient( - circle at 70% 30%, - rgba(255, 100, 100, 0.3) 0%, - transparent 50% - ); - animation: green-pulse 15s ease-in-out infinite alternate; -} - -@keyframes green-flow { - 0%, 100% { - transform: rotate(0deg) scale(1); - opacity: 0.8; - } - 25% { - transform: rotate(90deg) scale(1.1); - opacity: 0.6; - } - 50% { - transform: rotate(180deg) scale(0.9); - opacity: 0.9; - } - 75% { - transform: rotate(270deg) scale(1.05); - opacity: 0.7; - } -} - -@keyframes green-pulse { - 0% { - transform: scale(1) rotate(0deg); - opacity: 0.5; - } - 50% { - transform: scale(1.2) rotate(180deg); - opacity: 0.8; - } - 100% { - transform: scale(1) rotate(360deg); - opacity: 0.6; - } -} - -/* 手机端背景优化 */ -@media (max-width: 768px) { - .green-gradient { - animation-duration: 25s; - } - - .green-gradient::before { - animation-duration: 18s; - } -} - -/* 减少动画以节省电池 */ -@media (prefers-reduced-motion: reduce) { - .green-gradient, - .green-gradient::before { - animation: none; - } - - .green-gradient { - background: linear-gradient( - 135deg, - rgba(76, 175, 80, 0.2) 0%, - rgba(165, 214, 167, 0.1) 50%, - rgba(200, 230, 201, 0.15) 100% - ); - } -} \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/头条热搜榜/css/style.css b/frontend/60sapi/热搜榜单/头条热搜榜/css/style.css deleted file mode 100755 index e5904e78..00000000 --- a/frontend/60sapi/热搜榜单/头条热搜榜/css/style.css +++ /dev/null @@ -1,578 +0,0 @@ -/* 背景样式 */ -.background-container { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: -1; - overflow: hidden; - background-color: #f8f9fa; -} - -.modern-gradient { - position: absolute; - top: -50%; - left: -50%; - width: 200%; - height: 200%; - background: linear-gradient( - 135deg, - rgba(64, 169, 255, 0.4) 0%, - rgba(120, 192, 255, 0.3) 25%, - rgba(255, 175, 64, 0.2) 50%, - rgba(255, 140, 50, 0.3) 75%, - rgba(255, 122, 69, 0.4) 100% - ); - animation: gradient-flow 20s ease-in-out infinite; - border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%; -} - -.modern-gradient::before { - content: ''; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: radial-gradient( - circle at 30% 70%, - rgba(64, 169, 255, 0.5) 0%, - transparent 50% - ), radial-gradient( - circle at 70% 30%, - rgba(255, 140, 50, 0.4) 0%, - transparent 50% - ); - animation: pulse-effect 15s ease-in-out infinite alternate; - border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%; -} - -@keyframes gradient-flow { - 0%, 100% { - transform: rotate(0deg) scale(1); - opacity: 0.8; - } - 25% { - transform: rotate(90deg) scale(1.1); - opacity: 0.6; - } - 50% { - transform: rotate(180deg) scale(0.9); - opacity: 0.9; - } - 75% { - transform: rotate(270deg) scale(1.05); - opacity: 0.7; - } -} - -@keyframes pulse-effect { - 0% { - transform: scale(1) rotate(0deg); - opacity: 0.5; - } - 50% { - transform: scale(1.2) rotate(180deg); - opacity: 0.8; - } - 100% { - transform: scale(1) rotate(360deg); - opacity: 0.6; - } -} - -/* 主样式 */ -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -body { - font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif; - color: #333; - background-color: #f8f9fa; - position: relative; - min-height: 100vh; -} - -/* 几何装饰样式 */ -.title-container { - display: flex; - align-items: center; - justify-content: center; - margin-bottom: 10px; -} - -.geometric-decoration { - font-size: 20px; - color: #f04040; - margin: 0 15px; - font-weight: bold; - letter-spacing: 5px; - text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); - animation: float-effect 3s ease-in-out infinite alternate; -} - -.geometric-decoration.left { - transform: rotate(-10deg); -} - -.geometric-decoration.right { - transform: rotate(10deg); -} - -@keyframes float-effect { - 0% { - transform: translateY(0) rotate(-10deg); - } - 100% { - transform: translateY(-5px) rotate(-8deg); - } -} - -.update-time-container { - display: flex; - align-items: center; - justify-content: center; - margin-top: 10px; -} - -.time-decoration { - color: #f04040; - font-size: 18px; - margin: 0 10px; - animation: pulse 2s infinite; -} - -@keyframes pulse { - 0% { - opacity: 0.5; - transform: scale(0.8); - } - 50% { - opacity: 1; - transform: scale(1.2); - } - 100% { - opacity: 0.5; - transform: scale(0.8); - } -} - -.geometric-header, .geometric-footer { - text-align: center; - color: #f04040; - margin: 15px 0; - font-size: 16px; - letter-spacing: 3px; - opacity: 0.8; -} - -.geometric-header { - margin-bottom: 20px; -} - -.geometric-footer { - margin-top: 20px; -} - -.container { - max-width: 800px; - margin: 0 auto; - padding: 24px; - position: relative; - z-index: 1; - background-color: rgba(255, 255, 255, 0.85); - border-radius: 16px; - box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08); - backdrop-filter: blur(10px); - border: 2px solid rgba(240, 64, 64, 0.3); - position: relative; -} - -.container::before, -.container::after { - content: ''; - position: absolute; - width: 30px; - height: 30px; - border-color: #f04040; - opacity: 0.7; -} - -.container::before { - top: 10px; - left: 10px; - border-top: 3px solid; - border-left: 3px solid; - border-radius: 10px 0 0 0; -} - -.container::after { - bottom: 10px; - right: 10px; - border-bottom: 3px solid; - border-right: 3px solid; - border-radius: 0 0 10px 0; -} - -header { - text-align: center; - margin-bottom: 28px; - padding-bottom: 20px; - border-bottom: 1px solid rgba(0, 0, 0, 0.06); -} - -header h1 { - background: linear-gradient(135deg, #4096ff, #ff7a45); - -webkit-background-clip: text; - background-clip: text; - color: transparent; - margin-bottom: 14px; - font-size: 2.4rem; - font-weight: 700; - letter-spacing: -0.5px; -} - -.update-time { - color: #666; - font-size: 0.9rem; - background-color: rgba(0, 0, 0, 0.03); - padding: 8px 16px; - border-radius: 24px; - display: inline-block; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04); - position: relative; - border: 1px dashed rgba(240, 64, 64, 0.3); -} - -.update-time::before { - content: ''; - position: absolute; - top: -5px; - left: -5px; - right: -5px; - bottom: -5px; - border: 1px solid rgba(240, 64, 64, 0.3); - border-radius: 28px; - animation: pulse-border 2s infinite; - pointer-events: none; -} - -@keyframes pulse-border { - 0% { - transform: scale(1); - opacity: 0.7; - } - 50% { - transform: scale(1.05); - opacity: 0.3; - } - 100% { - transform: scale(1); - opacity: 0.7; - } -} - -.hot-list { - list-style: none; -} - -.hot-item { - padding: 20px; - margin-bottom: 16px; - border-radius: 12px; - background-color: white; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.04); - transition: all 0.3s ease; - display: flex; - align-items: center; - border: 1px solid rgba(0, 0, 0, 0.03); - position: relative; - overflow: hidden; -} - -.hot-item::before { - content: '◆'; - position: absolute; - top: 5px; - right: 10px; - color: #f04040; - opacity: 0.2; - font-size: 14px; -} - -.hot-item::after { - content: '◆'; - position: absolute; - bottom: 5px; - left: 10px; - color: #f04040; - opacity: 0.2; - font-size: 14px; -} - -.even-item { - border-left: 3px solid #f04040; -} - -.odd-item { - border-right: 3px solid #f04040; -} - -.title-decoration { - color: #f04040; - font-weight: bold; - margin-right: 5px; - display: inline-block; - transform: translateY(1px); -} - -.source-icon, .time-icon { - color: #f04040; - font-size: 14px; - margin-right: 3px; - opacity: 0.8; -} - -.hot-title { - position: relative; - display: inline-flex; - align-items: center; -} - -.hot-stats { - display: flex; - flex-wrap: wrap; - gap: 8px; - margin-top: 8px; -} - -.hot-item:hover { - transform: translateY(-3px); - box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08); - border-color: rgba(64, 169, 255, 0.3); -} - -.hot-rank { - font-size: 1.2rem; - font-weight: bold; - color: #4096ff; - margin-right: 18px; - min-width: 38px; - text-align: center; - background-color: rgba(64, 169, 255, 0.1); - border-radius: 50%; - width: 38px; - height: 38px; - display: flex; - align-items: center; - justify-content: center; -} - -.hot-rank.top-1 { - background: linear-gradient(135deg, #ff4d4f, #ff7a45); - color: white; -} - -.hot-rank.top-2 { - background: linear-gradient(135deg, #ff7a45, #ffa940); - color: white; -} - -.hot-rank.top-3 { - background: linear-gradient(135deg, #ffa940, #ffec3d); - color: white; -} - -.hot-content { - flex: 1; -} - -.hot-title { - font-size: 1.15rem; - margin-bottom: 8px; - color: #333; - text-decoration: none; - display: block; - line-height: 1.5; - font-weight: 500; - transition: color 0.2s ease; -} - -.hot-title:hover { - color: #4096ff; - text-decoration: none; -} - -.loading { - text-align: center; - padding: 40px; - color: #666; - font-size: 1.1rem; -} - -footer { - text-align: center; - margin-top: 40px; - padding-top: 20px; - border-top: 1px solid rgba(0, 0, 0, 0.06); - color: #999; - font-size: 0.9rem; -} - -.footer-decoration { - display: flex; - justify-content: center; - margin: 10px 0; - gap: 15px; -} - -.geo-symbol { - color: #f04040; - font-size: 16px; - opacity: 0.7; - transition: all 0.3s ease; - animation: color-shift 5s infinite alternate; -} - -.geo-symbol:hover { - opacity: 1; - transform: scale(1.2) rotate(15deg); -} - -@keyframes color-shift { - 0% { - color: #f04040; - } - 50% { - color: #ff7a45; - } - 100% { - color: #ff4d4f; - } -} - -/* 响应式设计 */ -@media (max-width: 1024px) and (min-width: 768px) { - .container { - max-width: 90%; - padding: 20px; - } - - header h1 { - font-size: 2.2rem; - } - - .hot-item { - padding: 18px; - } - - .hot-title { - font-size: 1.1rem; - } -} - -@media (max-width: 768px) { - body { - background-color: #f8f9fa; - } - - .container { - max-width: 95%; - margin: 12px auto; - padding: 16px; - border-radius: 12px; - } - - header { - margin-bottom: 20px; - padding-bottom: 16px; - } - - header h1 { - font-size: 1.8rem; - margin-bottom: 10px; - } - - .update-time { - font-size: 0.85rem; - padding: 6px 12px; - } - - .hot-item { - padding: 16px; - margin-bottom: 12px; - border-radius: 10px; - flex-direction: row; - align-items: flex-start; - } - - .hot-rank { - font-size: 1.1rem; - margin-right: 14px; - min-width: 32px; - width: 32px; - height: 32px; - margin-top: 2px; - } - - .hot-title { - font-size: 1rem; - line-height: 1.5; - margin-bottom: 6px; - } - - footer { - margin-top: 24px; - padding-top: 16px; - font-size: 0.85rem; - } -} - -@media (max-width: 480px) { - .container { - margin: 8px auto; - padding: 14px; - } - - header h1 { - font-size: 1.6rem; - } - - .hot-item { - padding: 14px; - margin-bottom: 10px; - } - - .hot-rank { - font-size: 1rem; - margin-right: 12px; - min-width: 30px; - width: 30px; - height: 30px; - } - - .hot-title { - font-size: 0.95rem; - } -} - -/* 减少动画以节省电池 */ -@media (prefers-reduced-motion: reduce) { - .modern-gradient, - .modern-gradient::before { - animation: none; - } - - .modern-gradient { - background: linear-gradient( - 135deg, - rgba(64, 169, 255, 0.3) 0%, - rgba(255, 175, 64, 0.2) 50%, - rgba(255, 122, 69, 0.25) 100% - ); - } -} \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/头条热搜榜/index.html b/frontend/60sapi/热搜榜单/头条热搜榜/index.html deleted file mode 100755 index bb45284f..00000000 --- a/frontend/60sapi/热搜榜单/头条热搜榜/index.html +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - 头条热搜榜 - - - - -
    -
    -
    - -
    -
    -
    -
    ◢ ◣ ▲
    -

    头条热搜榜

    -
    ▼ ◥ ◤
    -
    -
    - -
    - -
    -
    - -
    -
    - ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ -
    -
    -
    加载中...
    -
    - -
    - -
    - -

    数据来源于头条热搜榜

    - -
    -
    - - - - \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/头条热搜榜/js/main.js b/frontend/60sapi/热搜榜单/头条热搜榜/js/main.js deleted file mode 100755 index 2d7b0367..00000000 --- a/frontend/60sapi/热搜榜单/头条热搜榜/js/main.js +++ /dev/null @@ -1,171 +0,0 @@ -// API接口列表 -const API_ENDPOINTS = [ - "https://60s.api.shumengya.top/v2/toutiao", -]; - -// 当前使用的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 formatNumber(num) { - if (num >= 10000) { - return (num / 10000).toFixed(1) + '万'; - } - return num.toString(); -} - -// 渲染热搜列表 -function renderHotList(data) { - hotListElement.innerHTML = ''; - - // 几何装饰符号数组 - const geometricSymbols = ['◆', '■', '▲', '●', '★', '◈', '◇', '□', '△', '○']; - - data.forEach((item, index) => { - const hotItem = document.createElement('div'); - hotItem.className = 'hot-item'; - - const rankClass = index < 3 ? `top-${index + 1}` : ''; - - // 随机选择几何符号作为装饰 - const randomSymbol = geometricSymbols[index % geometricSymbols.length]; - - // 处理热度值显示 - const hotValueDisplay = item.hot_value ? - `
    ${randomSymbol} ${formatNumber(item.hot_value)} 热度
    ` : ''; - - // 处理标签显示 - const tagDisplay = item.tag ? - `
    ${randomSymbol} ${item.tag}
    ` : ''; - - hotItem.innerHTML = ` -
    ${index + 1}
    -
    - - ${randomSymbol} ${item.title} - -
    - ${hotValueDisplay} - ${tagDisplay} - ${item.source ? `
    ${randomSymbol} ${item.source}
    ` : ''} - ${item.time ? `
    ${randomSymbol} ${item.time}
    ` : ''} -
    -
    - `; - - hotListElement.appendChild(hotItem); - }); - - // 添加几何装饰到列表项 - const hotItems = document.querySelectorAll('.hot-item'); - hotItems.forEach((item, index) => { - // 为奇数和偶数项添加不同的装饰类 - if (index % 2 === 0) { - item.classList.add('even-item'); - } else { - item.classList.add('odd-item'); - } - }); - - // 更新时间 - updateTimeElement.textContent = `更新时间:${formatDate(new Date())}`; -} - -// 显示加载状态 -function showLoading() { - hotListElement.innerHTML = '
    加载中...
    '; -} - -// 显示错误状态 -function showError(message) { - hotListElement.innerHTML = `
    ${message}
    `; -} - -// 获取头条热搜数据 -async function fetchToutiaoHotList() { - showLoading(); - - try { - const response = await fetch(API_ENDPOINTS[currentApiIndex]); - - if (!response.ok) { - throw new Error(`HTTP ${response.status}: ${response.statusText}`); - } - - const result = await response.json(); - - if (result.code === 200 && result.data && Array.isArray(result.data)) { - if (result.data.length > 0) { - renderHotList(result.data); - } else { - showError('暂无热搜数据'); - } - } else { - throw new Error('数据格式错误或无数据'); - } - } catch (error) { - console.error('获取数据失败:', error); - - // 尝试切换到下一个API - const nextApiIndex = (currentApiIndex + 1) % API_ENDPOINTS.length; - - if (nextApiIndex !== 0) { - // 还有其他API可以尝试 - currentApiIndex = nextApiIndex; - showError('获取数据失败,正在尝试其他接口...'); - - // 延迟后重试 - setTimeout(fetchToutiaoHotList, 2000); - } else { - // 所有API都尝试过了 - currentApiIndex = 0; - showError('所有接口都无法访问,请稍后再试'); - } - } -} - -// 手动刷新数据 -function refreshData() { - currentApiIndex = 0; // 重置API索引 - fetchToutiaoHotList(); -} - -// 页面加载完成后获取数据 -document.addEventListener('DOMContentLoaded', () => { - fetchToutiaoHotList(); - - // 每隔5分钟刷新一次数据 - setInterval(fetchToutiaoHotList, 5 * 60 * 1000); - - // 添加键盘快捷键支持(按R键刷新) - document.addEventListener('keydown', (event) => { - if (event.key === 'r' || event.key === 'R') { - event.preventDefault(); - refreshData(); - } - }); -}); - -// 页面可见性变化时的处理 -document.addEventListener('visibilitychange', () => { - if (!document.hidden) { - // 页面重新可见时刷新数据 - refreshData(); - } -}); \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/头条热搜榜/接口集合.json b/frontend/60sapi/热搜榜单/头条热搜榜/接口集合.json deleted file mode 100755 index 547b2771..00000000 --- a/frontend/60sapi/热搜榜单/头条热搜榜/接口集合.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "https://60s.api.shumengya.top" -] diff --git a/frontend/60sapi/热搜榜单/头条热搜榜/返回接口.json b/frontend/60sapi/热搜榜单/头条热搜榜/返回接口.json deleted file mode 100755 index 778e5e45..00000000 --- a/frontend/60sapi/热搜榜单/头条热搜榜/返回接口.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "code": 200, - "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", - "data": [ - { - "title": "九三阅兵具体安排公布", - "hot_value": 11821633, - "tag": "热", - "source": "头条新闻", - "time": "2小时前", - "link": "https://www.toutiao.com/article/7404567890123456789/" - }, - { - "title": "九月第一天", - "hot_value": 11327170, - "tag": "新", - "source": "今日头条", - "time": "1小时前", - "link": "https://www.toutiao.com/article/7404567890123456790/" - }, - { - "title": "遇见上合共享津彩", - "hot_value": 11222444, - "tag": "推荐", - "source": "头条资讯", - "time": "3小时前", - "link": "https://www.toutiao.com/article/7404567890123456791/" - } - ] -} \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/微博热搜榜/css/background.css b/frontend/60sapi/热搜榜单/微博热搜榜/css/background.css deleted file mode 100755 index 4b71bd0d..00000000 --- a/frontend/60sapi/热搜榜单/微博热搜榜/css/background.css +++ /dev/null @@ -1,37 +0,0 @@ -.background-container { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: -1; - overflow: hidden; - background-color: #f8f9fa; -} - -.modern-gradient { - position: absolute; - top: -50%; - left: -50%; - width: 200%; - height: 200%; - background: linear-gradient( - 135deg, - rgba(230, 22, 45, 0.4) 0%, - rgba(245, 80, 80, 0.3) 25%, - rgba(250, 120, 110, 0.2) 50%, - rgba(255, 140, 140, 0.3) 75%, - rgba(255, 90, 90, 0.4) 100% - ); - animation: gradient-flow 20s ease-in-out infinite; - border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%; -} - -@keyframes rainbow-rotate { - 0% { - transform: rotate(0deg); - } - 100% { - transform: rotate(360deg); - } -} \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/微博热搜榜/css/style.css b/frontend/60sapi/热搜榜单/微博热搜榜/css/style.css deleted file mode 100755 index 0a661dcc..00000000 --- a/frontend/60sapi/热搜榜单/微博热搜榜/css/style.css +++ /dev/null @@ -1,384 +0,0 @@ -/* 背景样式 */ -.background-container { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: -1; - overflow: hidden; - background-color: #f8f9fa; -} - -.modern-gradient { - position: absolute; - top: -50%; - left: -50%; - width: 200%; - height: 200%; - background: linear-gradient( - 135deg, - rgba(64, 169, 255, 0.4) 0%, - rgba(120, 192, 255, 0.3) 25%, - rgba(255, 175, 64, 0.2) 50%, - rgba(255, 140, 50, 0.3) 75%, - rgba(255, 122, 69, 0.4) 100% - ); - animation: gradient-flow 20s ease-in-out infinite; - border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%; -} - -.modern-gradient::before { - content: ''; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: radial-gradient( - circle at 30% 70%, - rgba(64, 169, 255, 0.5) 0%, - transparent 50% - ), radial-gradient( - circle at 70% 30%, - rgba(255, 140, 50, 0.4) 0%, - transparent 50% - ); - animation: pulse-effect 15s ease-in-out infinite alternate; - border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%; -} - -@keyframes gradient-flow { - 0%, 100% { - transform: rotate(0deg) scale(1); - opacity: 0.8; - } - 25% { - transform: rotate(90deg) scale(1.1); - opacity: 0.6; - } - 50% { - transform: rotate(180deg) scale(0.9); - opacity: 0.9; - } - 75% { - transform: rotate(270deg) scale(1.05); - opacity: 0.7; - } -} - -@keyframes pulse-effect { - 0% { - transform: scale(1) rotate(0deg); - opacity: 0.5; - } - 50% { - transform: scale(1.2) rotate(180deg); - opacity: 0.8; - } - 100% { - transform: scale(1) rotate(360deg); - opacity: 0.6; - } -} - -/* 主样式 */ -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -body { - font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif; - color: #333; - background-color: #f8f9fa; - position: relative; - min-height: 100vh; -} - -/* 微博Logo样式 */ -.title-container { - display: flex; - flex-direction: column; - align-items: center; - margin-bottom: 10px; -} - -.weibo-logo-container { - margin-top: 10px; -} - -.weibo-logo { - background-color: #e6162d; - color: white; - font-weight: bold; - padding: 4px 10px; - border-radius: 15px; - font-size: 16px; - display: inline-block; - box-shadow: 0 2px 5px rgba(0,0,0,0.2); -} - -/* Q版眨眼动画样式 */ -.qeye-container { - display: flex; - justify-content: center; - margin-bottom: 10px; -} - -.qeye { - width: 80px; - height: 48px; -} - -.container { - max-width: 800px; - margin: 0 auto; - padding: 24px; - position: relative; - z-index: 1; - background-color: rgba(255, 255, 255, 0.85); - border-radius: 16px; - box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08); - backdrop-filter: blur(10px); -} - -header { - text-align: center; - margin-bottom: 28px; - padding-bottom: 20px; - border-bottom: 1px solid rgba(0, 0, 0, 0.06); -} - -header h1 { - background: linear-gradient(135deg, #4096ff, #ff7a45); - -webkit-background-clip: text; - background-clip: text; - color: transparent; - margin-bottom: 14px; - font-size: 2.4rem; - font-weight: 700; - letter-spacing: -0.5px; -} - -.update-time { - color: #666; - font-size: 0.9rem; - background-color: rgba(0, 0, 0, 0.03); - padding: 8px 16px; - border-radius: 24px; - display: inline-block; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04); -} - -.hot-list { - list-style: none; -} - -.hot-item { - padding: 20px; - margin-bottom: 16px; - border-radius: 12px; - background-color: white; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.04); - transition: all 0.3s ease; - display: flex; - align-items: center; - border: 1px solid rgba(0, 0, 0, 0.03); -} - -.hot-item:hover { - transform: translateY(-3px); - box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08); - border-color: rgba(64, 169, 255, 0.3); -} - -.hot-rank { - font-size: 1.2rem; - font-weight: bold; - color: #4096ff; - margin-right: 18px; - min-width: 38px; - text-align: center; - background-color: rgba(64, 169, 255, 0.1); - border-radius: 50%; - width: 38px; - height: 38px; - display: flex; - align-items: center; - justify-content: center; -} - -.hot-rank.top-1 { - background: linear-gradient(135deg, #ff4d4f, #ff7a45); - color: white; -} - -.hot-rank.top-2 { - background: linear-gradient(135deg, #ff7a45, #ffa940); - color: white; -} - -.hot-rank.top-3 { - background: linear-gradient(135deg, #ffa940, #ffec3d); - color: white; -} - -.hot-content { - flex: 1; -} - -.hot-title { - font-size: 1.15rem; - margin-bottom: 8px; - color: #333; - text-decoration: none; - display: block; - line-height: 1.5; - font-weight: 500; - transition: color 0.2s ease; -} - -.hot-title:hover { - color: #4096ff; - text-decoration: none; -} - -.loading { - text-align: center; - padding: 40px; - color: #666; - font-size: 1.1rem; -} - -footer { - text-align: center; - margin-top: 30px; - padding-top: 20px; - border-top: 1px solid rgba(0, 0, 0, 0.06); - color: #666; - font-size: 0.9rem; -} - -/* 响应式设计 */ -@media (max-width: 1024px) and (min-width: 768px) { - .container { - max-width: 90%; - padding: 20px; - } - - header h1 { - font-size: 2.2rem; - } - - .hot-item { - padding: 18px; - } - - .hot-title { - font-size: 1.1rem; - } -} - -@media (max-width: 768px) { - body { - background-color: #f8f9fa; - } - - .container { - max-width: 95%; - margin: 12px auto; - padding: 16px; - border-radius: 12px; - } - - header { - margin-bottom: 20px; - padding-bottom: 16px; - } - - header h1 { - font-size: 1.8rem; - margin-bottom: 10px; - } - - .update-time { - font-size: 0.85rem; - padding: 6px 12px; - } - - .hot-item { - padding: 16px; - margin-bottom: 12px; - border-radius: 10px; - flex-direction: row; - align-items: flex-start; - } - - .hot-rank { - font-size: 1.1rem; - margin-right: 14px; - min-width: 32px; - width: 32px; - height: 32px; - margin-top: 2px; - } - - .hot-title { - font-size: 1rem; - line-height: 1.5; - margin-bottom: 6px; - } - - footer { - margin-top: 24px; - padding-top: 16px; - font-size: 0.85rem; - } -} - -@media (max-width: 480px) { - .container { - margin: 8px auto; - padding: 14px; - } - - header h1 { - font-size: 1.6rem; - } - - .hot-item { - padding: 14px; - margin-bottom: 10px; - } - - .hot-rank { - font-size: 1rem; - margin-right: 12px; - min-width: 30px; - width: 30px; - height: 30px; - } - - .hot-title { - font-size: 0.95rem; - } -} - -/* 减少动画以节省电池 */ -@media (prefers-reduced-motion: reduce) { - .modern-gradient, - .modern-gradient::before { - animation: none; - } - - .modern-gradient { - background: linear-gradient( - 135deg, - rgba(64, 169, 255, 0.3) 0%, - rgba(255, 175, 64, 0.2) 50%, - rgba(255, 122, 69, 0.25) 100% - ); - } -} \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/微博热搜榜/img/qeye.svg b/frontend/60sapi/热搜榜单/微博热搜榜/img/qeye.svg deleted file mode 100755 index 4e14cff6..00000000 --- a/frontend/60sapi/热搜榜单/微博热搜榜/img/qeye.svg +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/微博热搜榜/index.html b/frontend/60sapi/热搜榜单/微博热搜榜/index.html deleted file mode 100755 index 45a71d19..00000000 --- a/frontend/60sapi/热搜榜单/微博热搜榜/index.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - 微博热搜榜 - - - - -
    -
    -
    - -
    -
    -

    🌈 微博热搜榜 🌈

    -
    -
    - -
    -
    -
    加载中...
    -
    -
    - -
    -

    数据来源于微博热搜榜

    -
    -
    - - - - \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/微博热搜榜/js/main.js b/frontend/60sapi/热搜榜单/微博热搜榜/js/main.js deleted file mode 100755 index 7e076706..00000000 --- a/frontend/60sapi/热搜榜单/微博热搜榜/js/main.js +++ /dev/null @@ -1,90 +0,0 @@ -// API接口列表 -const API_ENDPOINTS = [ - "https://60s.api.shumengya.top/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 = ` -
    ${index + 1}
    -
    - ${item.title} - ${item.hot_value ? `
    ${item.hot_value}
    ` : ''} -
    - `; - - 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 = ` -
    - 获取数据失败,正在尝试其他接口... -
    - `; - - // 延迟后重试 - setTimeout(fetchWeiboHotList, 2000); - } -} - -// 页面加载完成后获取数据 -document.addEventListener('DOMContentLoaded', () => { - fetchWeiboHotList(); - - // 每隔5分钟刷新一次数据 - setInterval(fetchWeiboHotList, 5 * 60 * 1000); -}); \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/微博热搜榜/接口集合.json b/frontend/60sapi/热搜榜单/微博热搜榜/接口集合.json deleted file mode 100755 index 547b2771..00000000 --- a/frontend/60sapi/热搜榜单/微博热搜榜/接口集合.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "https://60s.api.shumengya.top" -] diff --git a/frontend/60sapi/热搜榜单/微博热搜榜/返回接口.json b/frontend/60sapi/热搜榜单/微博热搜榜/返回接口.json deleted file mode 100755 index 0779a075..00000000 --- a/frontend/60sapi/热搜榜单/微博热搜榜/返回接口.json +++ /dev/null @@ -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" - } - ] -} \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/抖音热搜榜/css/background.css b/frontend/60sapi/热搜榜单/抖音热搜榜/css/background.css deleted file mode 100755 index fbf1fd3f..00000000 --- a/frontend/60sapi/热搜榜单/抖音热搜榜/css/background.css +++ /dev/null @@ -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); - } -} diff --git a/frontend/60sapi/热搜榜单/抖音热搜榜/css/style.css b/frontend/60sapi/热搜榜单/抖音热搜榜/css/style.css deleted file mode 100755 index 0c135ae8..00000000 --- a/frontend/60sapi/热搜榜单/抖音热搜榜/css/style.css +++ /dev/null @@ -1,535 +0,0 @@ -/* 背景样式 */ -.background-container { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: -1; - overflow: hidden; - background-color: #f8f9fa; -} - -.modern-gradient { - position: absolute; - top: -50%; - left: -50%; - width: 200%; - height: 200%; - background: linear-gradient( - 135deg, - rgba(64, 169, 255, 0.4) 0%, - rgba(120, 192, 255, 0.3) 25%, - rgba(255, 175, 64, 0.2) 50%, - rgba(255, 140, 50, 0.3) 75%, - rgba(255, 122, 69, 0.4) 100% - ); - animation: gradient-flow 20s ease-in-out infinite; - border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%; -} - -.modern-gradient::before { - content: ''; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: radial-gradient( - circle at 30% 70%, - rgba(64, 169, 255, 0.5) 0%, - transparent 50% - ), radial-gradient( - circle at 70% 30%, - rgba(255, 140, 50, 0.4) 0%, - transparent 50% - ); - animation: pulse-effect 15s ease-in-out infinite alternate; - border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%; -} - -@keyframes gradient-flow { - 0%, 100% { - transform: rotate(0deg) scale(1); - opacity: 0.8; - } - 25% { - transform: rotate(90deg) scale(1.1); - opacity: 0.6; - } - 50% { - transform: rotate(180deg) scale(0.9); - opacity: 0.9; - } - 75% { - transform: rotate(270deg) scale(1.05); - opacity: 0.7; - } -} - -@keyframes pulse-effect { - 0% { - transform: scale(1) rotate(0deg); - opacity: 0.5; - } - 50% { - transform: scale(1.2) rotate(180deg); - opacity: 0.8; - } - 100% { - transform: scale(1) rotate(360deg); - opacity: 0.6; - } -} - -/* 主样式 */ -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -body { - font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif; - color: #333; - background-color: #f8f9fa; - position: relative; - min-height: 100vh; -} - -.container { - max-width: 800px; - margin: 0 auto; - padding: 24px; - position: relative; - z-index: 1; - background-color: rgba(255, 255, 255, 0.85); - border-radius: 16px; - box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08); - backdrop-filter: blur(10px); -} - -header { - text-align: center; - margin-bottom: 28px; - padding-bottom: 20px; - border-bottom: 1px solid rgba(0, 0, 0, 0.06); -} - -header h1 { - background: linear-gradient(135deg, #4096ff, #ff7a45); - -webkit-background-clip: text; - background-clip: text; - color: transparent; - margin-bottom: 14px; - font-size: 2.4rem; - font-weight: 700; - letter-spacing: -0.5px; -} - -.update-time { - color: #666; - font-size: 0.9rem; - background-color: rgba(0, 0, 0, 0.03); - padding: 8px 16px; - border-radius: 24px; - display: inline-block; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04); -} - -/* 热搜列表 - 移动端优先设计 */ -.hot-list { - list-style: none; -} - -.hot-item { - background: white; - border-radius: 16px; - padding: 16px; - margin-bottom: 12px; - box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06); - transition: all 0.3s ease; - border: 1px solid rgba(0, 0, 0, 0.05); - display: flex; - align-items: center; - gap: 12px; - position: relative; - overflow: hidden; -} - -.hot-item:hover { - transform: translateY(-2px); - box-shadow: 0 6px 20px rgba(0, 0, 0, 0.1); - border-color: rgba(64, 169, 255, 0.2); -} - -/* 排名容器 */ -.hot-rank-container { - flex-shrink: 0; - display: flex; - align-items: center; -} - -.hot-rank { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - width: 48px; - height: 48px; - border-radius: 12px; - background: linear-gradient(135deg, #f0f0f0, #e8e8e8); - color: #666; - font-weight: 600; - position: relative; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); -} - -.hot-rank.rank-1 { - background: linear-gradient(135deg, #ff4d4f, #ff7a45); - color: white; - box-shadow: 0 4px 12px rgba(255, 77, 79, 0.3); -} - -.hot-rank.rank-2 { - background: linear-gradient(135deg, #ff7a45, #ffa940); - color: white; - box-shadow: 0 4px 12px rgba(255, 122, 69, 0.3); -} - -.hot-rank.rank-3 { - background: linear-gradient(135deg, #ffa940, #ffec3d); - color: #333; - box-shadow: 0 4px 12px rgba(255, 169, 64, 0.3); -} - -.rank-number { - font-size: 0.9rem; - font-weight: 700; - line-height: 1; -} - -.rank-emoji { - font-size: 0.7rem; - line-height: 1; - margin-top: 1px; -} - -/* 内容包装器 */ -.hot-content-wrapper { - flex: 1; - min-width: 0; - display: flex; - flex-direction: column; - justify-content: center; - gap: 8px; -} - -/* 标题 */ -.hot-title { - font-size: 1rem; - font-weight: 600; - color: #333; - line-height: 1.3; - margin: 0; - display: -webkit-box; - -webkit-line-clamp: 1; - -webkit-box-orient: vertical; - overflow: hidden; - text-overflow: ellipsis; - cursor: pointer; - transition: color 0.2s ease; -} - -.hot-title:hover { - color: #4096ff; -} - -/* 底部行 */ -.hot-bottom-row { - display: flex; - align-items: center; - gap: 12px; - flex-wrap: nowrap; -} - -.hot-time { - display: flex; - align-items: center; - gap: 4px; - color: #666; - font-size: 0.8rem; - flex-shrink: 0; -} - -.meta-icon { - font-size: 0.9rem; - flex-shrink: 0; -} - -.meta-text { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -.hot-value { - display: flex; - align-items: center; - gap: 4px; - background: linear-gradient(135deg, #ff6b6b, #4ecdc4); - color: white; - padding: 4px 10px; - border-radius: 12px; - font-size: 0.75rem; - font-weight: 600; - box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); - flex-shrink: 0; -} - -.heat-level { - font-size: 0.8rem; -} - -.value-text { - font-size: 0.75rem; -} - -/* 图片样式 */ -.hot-cover { - width: 80px; - height: 60px; - object-fit: cover; - border-radius: 8px; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); - flex-shrink: 0; -} - -.hot-link { - display: flex; - align-items: center; - gap: 4px; - background: linear-gradient(135deg, #4096ff, #40a9ff); - color: white; - text-decoration: none; - padding: 6px 12px; - border-radius: 12px; - font-size: 0.75rem; - font-weight: 600; - transition: all 0.3s ease; - box-shadow: 0 2px 6px rgba(64, 150, 255, 0.3); - flex-shrink: 0; -} - -.hot-link:hover { - transform: translateY(-1px); - box-shadow: 0 4px 10px rgba(64, 150, 255, 0.4); - text-decoration: none; - color: white; -} - -.link-icon { - font-size: 0.8rem; -} - -.link-text { - font-size: 0.75rem; -} - -.loading { - text-align: center; - padding: 40px; - color: #666; - font-size: 1.1rem; -} - -footer { - text-align: center; - margin-top: 30px; - padding-top: 20px; - border-top: 1px solid rgba(0, 0, 0, 0.06); - color: #666; - font-size: 0.9rem; -} - -/* 响应式设计 - 移动端优化 */ -@media (max-width: 1024px) and (min-width: 768px) { - .container { - max-width: 90%; - padding: 20px; - } - - header h1 { - font-size: 2.2rem; - } - - .hot-item { - padding: 18px; - gap: 14px; - } - - .hot-rank { - width: 52px; - height: 52px; - } - - .hot-title { - font-size: 1.1rem; - } -} - -@media (max-width: 768px) { - .container { - max-width: 95%; - margin: 12px auto; - padding: 8px; - border-radius: 12px; - } - - header { - margin-bottom: 20px; - padding: 12px 0 16px 0; - } - - header h1 { - font-size: 1.8rem; - margin-bottom: 10px; - } - - .update-time { - font-size: 0.85rem; - padding: 6px 12px; - } - - .hot-item { - padding: 12px; - margin-bottom: 10px; - gap: 10px; - } - - .hot-rank { - width: 40px; - height: 40px; - } - - .rank-number { - font-size: 0.8rem; - } - - .rank-emoji { - font-size: 0.6rem; - } - - .hot-title { - font-size: 0.9rem; - line-height: 1.3; - } - - .hot-meta-row { - gap: 8px; - } - - .hot-time { - font-size: 0.75rem; - } - - .hot-value { - padding: 3px 8px; - font-size: 0.7rem; - } - - .hot-cover { - width: 70px; - height: 50px; - } - - .hot-link { - padding: 5px 10px; - font-size: 0.7rem; - } - - .link-text { - font-size: 0.7rem; - } - - footer { - margin-top: 24px; - padding-top: 16px; - font-size: 0.85rem; - } -} - -@media (max-width: 480px) { - .container { - margin: 8px auto; - padding: 6px; - } - - header h1 { - font-size: 1.6rem; - } - - .hot-item { - padding: 10px; - margin-bottom: 8px; - gap: 8px; - } - - .hot-rank { - width: 36px; - height: 36px; - } - - .rank-number { - font-size: 0.75rem; - } - - .hot-title { - font-size: 0.85rem; - } - - .hot-meta-row { - flex-direction: column; - align-items: flex-start; - gap: 6px; - } - - .hot-media-row { - gap: 8px; - } - - .hot-time { - font-size: 0.7rem; - } - - .hot-value { - font-size: 0.65rem; - } - - .hot-cover { - width: 60px; - height: 45px; - } - - .hot-link { - font-size: 0.65rem; - padding: 4px 8px; - } -} - -/* 减少动画以节省电池 */ -@media (prefers-reduced-motion: reduce) { - .modern-gradient, - .modern-gradient::before { - animation: none; - } - - .modern-gradient { - background: linear-gradient( - 135deg, - rgba(64, 169, 255, 0.3) 0%, - rgba(255, 175, 64, 0.2) 50%, - rgba(255, 122, 69, 0.25) 100% - ); - } -} \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/抖音热搜榜/index.html b/frontend/60sapi/热搜榜单/抖音热搜榜/index.html deleted file mode 100755 index 9892695a..00000000 --- a/frontend/60sapi/热搜榜单/抖音热搜榜/index.html +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - 抖音热搜榜 - - - - -
    -
    -
    🔥
    -

    📱 抖音热搜榜 🎵

    -

    实时热门话题 · 紧跟潮流趋势

    -
    - - 加载中... -
    - -
    - -
    -
    -
    -
    - 🎭 -

    正在获取最新热搜...

    -
    - - - -
    -
    -
    -
    - -
    - -
    - - -
    - - - - diff --git a/frontend/60sapi/热搜榜单/抖音热搜榜/js/script.js b/frontend/60sapi/热搜榜单/抖音热搜榜/js/script.js deleted file mode 100755 index 68ee67d2..00000000 --- a/frontend/60sapi/热搜榜单/抖音热搜榜/js/script.js +++ /dev/null @@ -1,332 +0,0 @@ -// 本地后端API接口 -const LOCAL_API_BASE = 'https://infogenie.api.shumengya.top/api/60s'; - -// API接口列表(备用) -const API_ENDPOINTS = [ - "https://60s.api.shumengya.top", -]; - -// 当前使用的API索引 -let currentApiIndex = 0; -let useLocalApi = true; - -// 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() { - // 优先尝试本地API - if (useLocalApi) { - try { - const response = await fetch(`${LOCAL_API_BASE}/douyin`, { - method: 'GET', - headers: { - 'Accept': 'application/json', - }, - timeout: 10000 - }); - - if (response.ok) { - const data = await response.json(); - if (data.code === 200 && data.data) { - return data; - } - } - } catch (error) { - console.warn('本地API请求失败,切换到外部API:', error); - useLocalApi = false; - } - } - - // 使用外部API作为备用 - 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'; - - // 排名样式类 - let rankClass = 'hot-rank'; - if (rank === 1) rankClass += ' rank-1'; - else if (rank === 2) rankClass += ' rank-2'; - else if (rank === 3) rankClass += ' rank-3'; - - 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 = '🔥'; - - // 根据热度值添加火焰等级 - let fireLevel = ''; - if (item.hot_value >= 10000000) fireLevel = '🔥🔥🔥'; - else if (item.hot_value >= 5000000) fireLevel = '🔥🔥'; - else fireLevel = '🔥'; - - hotItem.innerHTML = ` -
    -
    -
    ${rank}
    -
    ${rankEmoji}
    -
    -
    - ${escapeHtml(item.title)} -
    -
    ${escapeHtml(item.title)}
    -
    -
    - - ${formattedTime} -
    -
    - ${fireLevel} - ${formattedHotValue} -
    - - 🎬 - 观看视频 - -
    -
    - `; - - 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); diff --git a/frontend/60sapi/热搜榜单/抖音热搜榜/接口集合.json b/frontend/60sapi/热搜榜单/抖音热搜榜/接口集合.json deleted file mode 100755 index 547b2771..00000000 --- a/frontend/60sapi/热搜榜单/抖音热搜榜/接口集合.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "https://60s.api.shumengya.top" -] diff --git a/frontend/60sapi/热搜榜单/抖音热搜榜/返回接口.json b/frontend/60sapi/热搜榜单/抖音热搜榜/返回接口.json deleted file mode 100755 index 5094d4ec..00000000 --- a/frontend/60sapi/热搜榜单/抖音热搜榜/返回接口.json +++ /dev/null @@ -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 - } - ] -} \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/猫眼票房排行榜/css/style.css b/frontend/60sapi/热搜榜单/猫眼票房排行榜/css/style.css deleted file mode 100755 index 7f70c9a0..00000000 --- a/frontend/60sapi/热搜榜单/猫眼票房排行榜/css/style.css +++ /dev/null @@ -1,582 +0,0 @@ -/* 现代化猫眼票房排行榜样式 */ - -/* 全局重置和基础样式 */ -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -:root { - /* 主色调 */ - --primary-color: #667eea; - --primary-light: #764ba2; - --secondary-color: #f093fb; - --accent-color: #4facfe; - - /* 中性色 */ - --text-primary: #2d3748; - --text-secondary: #4a5568; - --text-muted: #718096; - --bg-primary: #ffffff; - --bg-secondary: #f7fafc; - --bg-tertiary: #edf2f7; - - /* 状态色 */ - --success-color: #48bb78; - --warning-color: #ed8936; - --error-color: #f56565; - - /* 阴影 */ - --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.1); - --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1); - --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1); - --shadow-xl: 0 20px 25px rgba(0, 0, 0, 0.15); - - /* 圆角 */ - --radius-sm: 6px; - --radius-md: 12px; - --radius-lg: 16px; - --radius-xl: 24px; - - /* 间距 */ - --space-xs: 4px; - --space-sm: 8px; - --space-md: 16px; - --space-lg: 24px; - --space-xl: 32px; - --space-2xl: 48px; -} - -body { - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif; - line-height: 1.6; - color: var(--text-primary); - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - min-height: 100vh; - position: relative; - overflow-x: hidden; -} - -/* 动态背景效果 */ -body::before { - content: ''; - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: - radial-gradient(circle at 20% 80%, rgba(120, 119, 198, 0.3) 0%, transparent 50%), - radial-gradient(circle at 80% 20%, rgba(255, 119, 198, 0.3) 0%, transparent 50%), - radial-gradient(circle at 40% 40%, rgba(120, 219, 255, 0.2) 0%, transparent 50%); - z-index: -1; - animation: backgroundShift 20s ease-in-out infinite; -} - -@keyframes backgroundShift { - 0%, 100% { - transform: scale(1) rotate(0deg); - opacity: 0.8; - } - 50% { - transform: scale(1.1) rotate(180deg); - opacity: 0.6; - } -} - -/* 主容器 */ -.container { - max-width: 900px; - margin: var(--space-lg) auto; - padding: var(--space-xl); - background: rgba(255, 255, 255, 0.95); - backdrop-filter: blur(20px); - border-radius: var(--radius-xl); - box-shadow: var(--shadow-xl); - border: 1px solid rgba(255, 255, 255, 0.2); - position: relative; - animation: slideUp 0.8s ease-out; -} - -@keyframes slideUp { - from { - opacity: 0; - transform: translateY(30px); - } - to { - opacity: 1; - transform: translateY(0); - } -} - -/* 头部样式 */ -.header { - text-align: center; - margin-bottom: var(--space-2xl); - padding-bottom: var(--space-lg); - border-bottom: 2px solid var(--bg-tertiary); - position: relative; -} - -.header::after { - content: ''; - position: absolute; - bottom: -2px; - left: 50%; - transform: translateX(-50%); - width: 60px; - height: 4px; - background: linear-gradient(90deg, var(--primary-color), var(--secondary-color)); - border-radius: 2px; -} - -.header h1 { - display: flex; - align-items: center; - justify-content: center; - gap: var(--space-md); - margin-bottom: var(--space-md); - font-size: clamp(1.8rem, 4vw, 2.5rem); - font-weight: 700; - letter-spacing: -0.02em; - flex-wrap: wrap; -} - -.header h1 .icon { - font-size: 1.2em; - animation: bounce 2s infinite; - filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.1)); -} - -@keyframes bounce { - 0%, 20%, 50%, 80%, 100% { - transform: translateY(0); - } - 40% { - transform: translateY(-8px); - } - 60% { - transform: translateY(-4px); - } -} - -.header h1 .title-text { - background: linear-gradient(135deg, var(--primary-color), var(--primary-light)); - -webkit-background-clip: text; - background-clip: text; - color: transparent; - position: relative; -} - -.header h1 .update-badge { - font-size: 0.4em; - background: linear-gradient(135deg, var(--accent-color), var(--secondary-color)); - color: white; - padding: var(--space-xs) var(--space-md); - border-radius: var(--radius-xl); - font-weight: 600; - box-shadow: var(--shadow-md); - animation: pulse 3s infinite; - white-space: nowrap; -} - -@keyframes pulse { - 0%, 100% { - transform: scale(1); - box-shadow: var(--shadow-md); - } - 50% { - transform: scale(1.05); - box-shadow: var(--shadow-lg); - } -} - -.header-desc { - color: var(--text-secondary); - font-size: 1.1rem; - font-weight: 500; - margin-top: var(--space-sm); -} - -/* 加载状态 */ -.loading { - text-align: center; - padding: var(--space-2xl); - color: var(--text-secondary); -} - -.spinner { - width: 40px; - height: 40px; - margin: 0 auto var(--space-md); - border: 3px solid var(--bg-tertiary); - border-top: 3px solid var(--primary-color); - border-radius: 50%; - animation: spin 1s linear infinite; -} - -@keyframes spin { - 0% { transform: rotate(0deg); } - 100% { transform: rotate(360deg); } -} - -/* 内容区域 */ -.content { - animation: fadeIn 0.6s ease-out 0.2s both; -} - -@keyframes fadeIn { - from { - opacity: 0; - transform: translateY(20px); - } - to { - opacity: 1; - transform: translateY(0); - } -} - -.ranking-title { - font-size: 1.5rem; - font-weight: 600; - color: var(--text-primary); - margin-bottom: var(--space-lg); - text-align: center; - position: relative; -} - -/* 电影列表 */ -.movie-list { - display: flex; - flex-direction: column; - gap: var(--space-md); -} - -.movie-item { - display: flex; - align-items: center; - gap: var(--space-md); - padding: var(--space-lg); - background: var(--bg-primary); - border-radius: var(--radius-lg); - box-shadow: var(--shadow-sm); - border: 1px solid rgba(0, 0, 0, 0.05); - transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); - position: relative; - overflow: hidden; -} - -.movie-item::before { - content: ''; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: linear-gradient(135deg, transparent 0%, rgba(102, 126, 234, 0.02) 100%); - opacity: 0; - transition: opacity 0.3s ease; -} - -.movie-item:hover { - transform: translateY(-4px); - box-shadow: var(--shadow-lg); - border-color: rgba(102, 126, 234, 0.2); -} - -.movie-item:hover::before { - opacity: 1; -} - -/* 特殊排名样式 */ -.movie-item.top-1 { - background: linear-gradient(135deg, rgba(255, 215, 0, 0.1) 0%, var(--bg-primary) 100%); - border-color: rgba(255, 215, 0, 0.3); -} - -.movie-item.top-2 { - background: linear-gradient(135deg, rgba(192, 192, 192, 0.1) 0%, var(--bg-primary) 100%); - border-color: rgba(192, 192, 192, 0.3); -} - -.movie-item.top-3 { - background: linear-gradient(135deg, rgba(205, 127, 50, 0.1) 0%, var(--bg-primary) 100%); - border-color: rgba(205, 127, 50, 0.3); -} - -/* 排名徽章 */ -.movie-rank { - display: flex; - align-items: center; - justify-content: center; - width: 50px; - height: 50px; - border-radius: var(--radius-md); - font-size: 1.2rem; - font-weight: 700; - flex-shrink: 0; - transition: all 0.3s ease; - position: relative; -} - -.movie-item:hover .movie-rank { - transform: scale(1.1); -} - -.movie-rank.gold { - background: linear-gradient(135deg, #ffd700, #ffb700); - color: white; - box-shadow: 0 4px 15px rgba(255, 215, 0, 0.4); -} - -.movie-rank.silver { - background: linear-gradient(135deg, #c0c0c0, #a0a0a0); - color: white; - box-shadow: 0 4px 15px rgba(192, 192, 192, 0.4); -} - -.movie-rank.bronze { - background: linear-gradient(135deg, #cd7f32, #b06728); - color: white; - box-shadow: 0 4px 15px rgba(205, 127, 50, 0.4); -} - -.movie-rank.regular { - background: linear-gradient(135deg, var(--primary-color), var(--accent-color)); - color: white; - box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3); -} - -/* 电影内容 */ -.movie-content { - flex: 1; - display: flex; - flex-direction: column; - gap: var(--space-sm); - min-width: 0; -} - -.movie-title { - font-size: 1.1rem; - font-weight: 600; - color: var(--text-primary); - line-height: 1.4; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -.movie-meta { - display: flex; - align-items: center; - justify-content: space-between; - gap: var(--space-md); - flex-wrap: wrap; -} - -.movie-year { - color: var(--text-muted); - font-size: 0.85rem; - background: var(--bg-tertiary); - padding: var(--space-xs) var(--space-sm); - border-radius: var(--radius-sm); - font-weight: 500; -} - -.movie-boxoffice { - font-weight: 700; - color: var(--warning-color); - font-size: 1rem; - white-space: nowrap; -} - -/* 更新时间 */ -.update-time { - text-align: center; - margin-top: var(--space-lg); - padding: var(--space-md); - background: var(--bg-secondary); - border-radius: var(--radius-md); - color: var(--text-secondary); - font-size: 0.9rem; - border: 1px solid var(--bg-tertiary); -} - -/* 错误状态 */ -.error { - text-align: center; - padding: var(--space-2xl); - color: var(--error-color); -} - -.error h3 { - font-size: 1.2rem; - margin-bottom: var(--space-md); -} - -.error p { - margin-bottom: var(--space-sm); - color: var(--text-secondary); -} - -/* 响应式设计 */ -@media (max-width: 768px) { - .container { - margin: var(--space-md); - padding: var(--space-lg); - border-radius: var(--radius-lg); - } - - .header { - margin-bottom: var(--space-lg); - padding-bottom: var(--space-md); - } - - .header h1 { - font-size: 1.8rem; - gap: var(--space-sm); - } - - .header h1 .update-badge { - font-size: 0.35em; - padding: 2px var(--space-sm); - } - - .movie-item { - padding: var(--space-md); - gap: var(--space-sm); - } - - .movie-rank { - width: 42px; - height: 42px; - font-size: 1rem; - } - - .movie-title { - font-size: 1rem; - } - - .movie-meta { - gap: var(--space-sm); - } - - .movie-year { - font-size: 0.8rem; - } - - .movie-boxoffice { - font-size: 0.9rem; - } -} - -@media (max-width: 480px) { - .container { - margin: var(--space-sm); - padding: var(--space-md); - } - - .header h1 { - font-size: 1.6rem; - flex-direction: column; - gap: var(--space-xs); - } - - .movie-list { - gap: var(--space-sm); - } - - .movie-item { - padding: var(--space-sm); - } - - .movie-rank { - width: 38px; - height: 38px; - font-size: 0.9rem; - } - - .movie-title { - font-size: 0.95rem; - } - - .movie-meta { - flex-direction: column; - align-items: flex-start; - gap: var(--space-xs); - } -} - -/* 减少动画以节省电池 */ -@media (prefers-reduced-motion: reduce) { - *, - *::before, - *::after { - animation-duration: 0.01ms !important; - animation-iteration-count: 1 !important; - transition-duration: 0.01ms !important; - } - - body::before { - animation: none; - } -} - -/* 深色模式支持 */ -@media (prefers-color-scheme: dark) { - :root { - --text-primary: #f7fafc; - --text-secondary: #e2e8f0; - --text-muted: #a0aec0; - --bg-primary: #2d3748; - --bg-secondary: #4a5568; - --bg-tertiary: #718096; - } - - body { - background: linear-gradient(135deg, #2d3748 0%, #4a5568 100%); - } - - .container { - background: rgba(45, 55, 72, 0.95); - border-color: rgba(255, 255, 255, 0.1); - } - - .movie-item { - background: var(--bg-primary); - border-color: rgba(255, 255, 255, 0.1); - } - - .movie-item:hover { - border-color: rgba(102, 126, 234, 0.4); - } -} - -/* 打印样式 */ -@media print { - body { - background: white; - color: black; - } - - body::before { - display: none; - } - - .container { - background: white; - box-shadow: none; - border: 1px solid #ccc; - } - - .movie-item { - break-inside: avoid; - box-shadow: none; - border: 1px solid #ddd; - } - - .header h1 .update-badge { - background: #666; - } -} \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/猫眼票房排行榜/index.html b/frontend/60sapi/热搜榜单/猫眼票房排行榜/index.html deleted file mode 100755 index 8ce9b1b3..00000000 --- a/frontend/60sapi/热搜榜单/猫眼票房排行榜/index.html +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - 猫眼票房排行榜 | 全球电影总票房 - - - - - - - - -
    - -
    -

    - 🎬 - 猫眼票房排行榜 - 实时更新 -

    -

    全球电影总票房榜单 | 权威数据 | 实时更新

    -
    - - -
    -
    -

    正在加载票房数据...

    -
    - - -
    -
    - - - - - \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/猫眼票房排行榜/js/script.js b/frontend/60sapi/热搜榜单/猫眼票房排行榜/js/script.js deleted file mode 100755 index b66a2537..00000000 --- a/frontend/60sapi/热搜榜单/猫眼票房排行榜/js/script.js +++ /dev/null @@ -1,266 +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.api.shumengya.top/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 = ` -
    -

    全球电影总票房排行榜

    -
    - ${list.map(item => renderMovieItem(item)).join('')} -
    -
    - ${tip ? `
    ${escapeHtml(tip)}
    ` : ''} - ${update_time ? `
    更新时间:${escapeHtml(update_time)}
    ` : ''} - `; - - elements.container.innerHTML = html; - elements.container.classList.add('fade-in'); -} - -// 格式化票房数据,将数字转换为更易读的形式 -function formatBoxOffice(value) { - if (!value) return '未知'; - - // 将字符串转换为数字 - const num = typeof value === 'string' ? parseFloat(value.replace(/[^0-9.]/g, '')) : value; - - if (isNaN(num)) return value; - - if (num >= 100000000) { - return (num / 100000000).toFixed(2) + ' 亿'; - } else if (num >= 10000) { - return (num / 10000).toFixed(2) + ' 万'; - } else { - return num.toLocaleString(); - } -} - -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'; - - // 格式化票房数据 - const boxOffice = formatBoxOffice(item.boxoffice || item.box_office); - - // 美化排名显示 - let rankDisplay; - if (rank === 1) { - rankDisplay = '🏆'; - } else if (rank === 2) { - rankDisplay = '🥈'; - } else if (rank === 3) { - rankDisplay = '🥉'; - } else { - rankDisplay = rank; - } - - return ` -
    -
    ${rankDisplay}
    -
    -
    ${escapeHtml(item.movie_name)}
    -
    - ${escapeHtml(item.release_year || '未知')} - ¥${boxOffice} -
    -
    -
    `; -} - - -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 = ` -
    -

    ⚠️ 加载失败

    -

    ${escapeHtml(message)}

    -

    请稍后重试

    -
    - `; - 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(); - } -}); \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/猫眼票房排行榜/接口集合.json b/frontend/60sapi/热搜榜单/猫眼票房排行榜/接口集合.json deleted file mode 100755 index 547b2771..00000000 --- a/frontend/60sapi/热搜榜单/猫眼票房排行榜/接口集合.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "https://60s.api.shumengya.top" -] diff --git a/frontend/60sapi/热搜榜单/猫眼票房排行榜/返回接口.json b/frontend/60sapi/热搜榜单/猫眼票房排行榜/返回接口.json deleted file mode 100755 index 945e5cfe..00000000 --- a/frontend/60sapi/热搜榜单/猫眼票房排行榜/返回接口.json +++ /dev/null @@ -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 - } -} \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/知乎热门话题/css/background.css b/frontend/60sapi/热搜榜单/知乎热门话题/css/background.css deleted file mode 100755 index 000933fd..00000000 --- a/frontend/60sapi/热搜榜单/知乎热门话题/css/background.css +++ /dev/null @@ -1,108 +0,0 @@ -.background-container { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: -1; - overflow: hidden; -} - -.green-gradient { - position: absolute; - top: -50%; - left: -50%; - width: 200%; - height: 200%; - background: linear-gradient( - 135deg, - rgba(0, 132, 255, 0.4) 0%, - rgba(0, 132, 255, 0.3) 25%, - rgba(0, 132, 255, 0.2) 50%, - rgba(0, 132, 255, 0.3) 75%, - rgba(0, 132, 255, 0.4) 100% - ); - animation: gradient-flow 20s ease-in-out infinite; - border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%; -} - -.green-gradient::before { - content: ''; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: radial-gradient( - circle at 30% 70%, - rgba(139, 195, 74, 0.4) 0%, - transparent 50% - ), radial-gradient( - circle at 70% 30%, - rgba(102, 187, 106, 0.3) 0%, - transparent 50% - ); - animation: green-pulse 15s ease-in-out infinite alternate; -} - -@keyframes green-flow { - 0%, 100% { - transform: rotate(0deg) scale(1); - opacity: 0.8; - } - 25% { - transform: rotate(90deg) scale(1.1); - opacity: 0.6; - } - 50% { - transform: rotate(180deg) scale(0.9); - opacity: 0.9; - } - 75% { - transform: rotate(270deg) scale(1.05); - opacity: 0.7; - } -} - -@keyframes green-pulse { - 0% { - transform: scale(1) rotate(0deg); - opacity: 0.5; - } - 50% { - transform: scale(1.2) rotate(180deg); - opacity: 0.8; - } - 100% { - transform: scale(1) rotate(360deg); - opacity: 0.6; - } -} - -/* 手机端背景优化 */ -@media (max-width: 768px) { - .green-gradient { - animation-duration: 25s; - } - - .green-gradient::before { - animation-duration: 18s; - } -} - -/* 减少动画以节省电池 */ -@media (prefers-reduced-motion: reduce) { - .green-gradient, - .green-gradient::before { - animation: none; - } - - .green-gradient { - background: linear-gradient( - 135deg, - rgba(76, 175, 80, 0.2) 0%, - rgba(165, 214, 167, 0.1) 50%, - rgba(200, 230, 201, 0.15) 100% - ); - } -} \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/知乎热门话题/css/style.css b/frontend/60sapi/热搜榜单/知乎热门话题/css/style.css deleted file mode 100755 index c5a43c03..00000000 --- a/frontend/60sapi/热搜榜单/知乎热门话题/css/style.css +++ /dev/null @@ -1,499 +0,0 @@ -/* 背景样式 */ -.background-container { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: -1; - overflow: hidden; - background-color: #f8f9fa; -} - -.modern-gradient { - position: absolute; - top: -50%; - left: -50%; - width: 200%; - height: 200%; - background: linear-gradient( - 135deg, - rgba(64, 169, 255, 0.4) 0%, - rgba(120, 192, 255, 0.3) 25%, - rgba(255, 175, 64, 0.2) 50%, - rgba(255, 140, 50, 0.3) 75%, - rgba(255, 122, 69, 0.4) 100% - ); - animation: gradient-flow 20s ease-in-out infinite; - border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%; -} - -.modern-gradient::before { - content: ''; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: radial-gradient( - circle at 30% 70%, - rgba(64, 169, 255, 0.5) 0%, - transparent 50% - ), radial-gradient( - circle at 70% 30%, - rgba(255, 140, 50, 0.4) 0%, - transparent 50% - ); - animation: pulse-effect 15s ease-in-out infinite alternate; - border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%; -} - -@keyframes gradient-flow { - 0%, 100% { - transform: rotate(0deg) scale(1); - opacity: 0.8; - } - 25% { - transform: rotate(90deg) scale(1.1); - opacity: 0.6; - } - 50% { - transform: rotate(180deg) scale(0.9); - opacity: 0.9; - } - 75% { - transform: rotate(270deg) scale(1.05); - opacity: 0.7; - } -} - -@keyframes pulse-effect { - 0% { - transform: scale(1) rotate(0deg); - opacity: 0.5; - } - 50% { - transform: scale(1.2) rotate(180deg); - opacity: 0.8; - } - 100% { - transform: scale(1) rotate(360deg); - opacity: 0.6; - } -} - -/* 主样式 */ -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -body { - font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif; - color: #333; - background-color: #f8f9fa; - position: relative; - min-height: 100vh; - line-height: 1.6; -} - -.container { - max-width: 800px; - margin: 0 auto; - padding: 24px; - position: relative; - z-index: 1; - background-color: rgba(255, 255, 255, 0.85); - border-radius: 16px; - box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08); - backdrop-filter: blur(10px); -} - -header { - text-align: center; - margin-bottom: 28px; - padding-bottom: 20px; - border-bottom: 1px solid rgba(0, 0, 0, 0.06); -} - -header h1 { - background: linear-gradient(135deg, #4096ff, #ff7a45); - -webkit-background-clip: text; - background-clip: text; - color: transparent; - margin-bottom: 14px; - font-size: 2.4rem; - font-weight: 700; - letter-spacing: -0.5px; -} - -.update-time { - color: #666; - font-size: 0.9rem; - background-color: rgba(0, 0, 0, 0.03); - padding: 8px 16px; - border-radius: 24px; - display: inline-block; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04); -} - -.hot-list { - list-style: none; -} - -.hot-item { - padding: 20px; - margin-bottom: 16px; - border-radius: 12px; - background-color: white; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.04); - transition: all 0.3s ease; - display: flex; - align-items: center; - border: 1px solid rgba(0, 0, 0, 0.03); -} - -.hot-item:hover { - transform: translateY(-3px); - box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08); - border-color: rgba(64, 169, 255, 0.3); -} - -.hot-rank { - font-size: 1.2rem; - font-weight: bold; - color: #4096ff; - margin-right: 18px; - min-width: 38px; - text-align: center; - background-color: rgba(64, 169, 255, 0.1); - border-radius: 50%; - width: 38px; - height: 38px; - display: flex; - align-items: center; - justify-content: center; -} - -.hot-rank.top-1 { - background: linear-gradient(135deg, #ff4d4f, #ff7a45); - color: white; -} - -.hot-rank.top-2 { - background: linear-gradient(135deg, #ff7a45, #ffa940); - color: white; -} - -.hot-rank.top-3 { - background: linear-gradient(135deg, #ffa940, #ffec3d); - color: white; -} - -.hot-content { - flex: 1; -} - -.hot-title { - font-size: 1.15rem; - margin-bottom: 8px; - color: #333; - text-decoration: none; - display: block; - line-height: 1.5; - font-weight: 500; - transition: color 0.2s ease; -} - -.hot-title:hover { - color: #4096ff; - text-decoration: none; -} - -.loading { - text-align: center; - padding: 40px; - color: #666; - font-size: 1.1rem; -} - -footer { - text-align: center; - margin-top: 30px; - padding-top: 20px; - border-top: 1px solid rgba(0, 0, 0, 0.06); - color: #666; - font-size: 0.9rem; -} - -/* 新增样式 */ -.topic-header { - display: flex; - flex-wrap: wrap; - align-items: flex-start; - width: 100%; -} - -/* 短内容时的布局 - 图片在右侧 */ -.topic-header.short-content { - flex-direction: row; -} - -/* 长内容时的布局 - 图片在下方 */ -.topic-header.long-content { - flex-direction: column; -} - -.topic-rank { - font-size: 1.2rem; - font-weight: bold; - color: #4096ff; - margin-right: 16px; - min-width: 36px; - text-align: center; - background-color: rgba(64, 169, 255, 0.1); - border-radius: 50%; - width: 36px; - height: 36px; - display: flex; - align-items: center; - justify-content: center; -} - -.topic-rank.top-1 { - background: linear-gradient(135deg, #ff4d4f, #ff7a45); - color: white; -} - -.topic-rank.top-2 { - background: linear-gradient(135deg, #ff7a45, #ffa940); - color: white; -} - -.topic-rank.top-3 { - background: linear-gradient(135deg, #ffa940, #ffec3d); - color: white; -} - -.topic-content { - flex: 1; - padding-right: 16px; -} - -.topic-title { - font-size: 1.15rem; - margin-bottom: 8px; - color: #333; - text-decoration: none; - display: block; - line-height: 1.5; - font-weight: 600; - transition: color 0.2s ease; -} - -.topic-title:hover { - color: #4096ff; -} - -.topic-detail { - color: #666; - font-size: 0.95rem; - line-height: 1.6; - margin-bottom: 10px; - text-align: justify; - text-indent: 2em; -} - -.topic-stats { - display: flex; - flex-wrap: wrap; - gap: 12px; - margin-top: 8px; - font-size: 0.85rem; - color: #666; -} - -.stat-item { - display: flex; - align-items: center; -} - -.hot-value { - color: #ff4d4f; - font-weight: 500; -} - -/* 短内容时的图片样式 - 在右侧 */ -.short-content .topic-cover { - width: 120px; - height: 80px; - object-fit: cover; - border-radius: 8px; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); - align-self: center; - margin-left: auto; -} - -/* 长内容时的图片样式 - 在下方 */ -.long-content .topic-cover { - width: 100%; - height: auto; - max-height: none; - object-fit: contain; - border-radius: 8px; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); - margin-top: 12px; - margin-left: 0; - margin-bottom: 8px; -} - -.topic-item { - padding: 20px; - margin-bottom: 16px; - border-radius: 12px; - background-color: white; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.04); - transition: all 0.3s ease; - border: 1px solid rgba(0, 0, 0, 0.03); -} - -.topic-item:hover { - transform: translateY(-3px); - box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08); - border-color: rgba(64, 169, 255, 0.3); -} - -/* 响应式设计 */ -@media (max-width: 1024px) and (min-width: 768px) { - .container { - max-width: 90%; - padding: 20px; - } - - header h1 { - font-size: 2.2rem; - } - - .topic-item { - padding: 18px; - } - - .topic-title { - font-size: 1.1rem; - } - - .topic-cover { - width: 100px; - height: 70px; - } -} - -@media (max-width: 768px) { - body { - background-color: #f8f9fa; - } - - .container { - max-width: 95%; - margin: 12px auto; - padding: 16px; - border-radius: 12px; - } - - header { - margin-bottom: 20px; - padding-bottom: 16px; - } - - header h1 { - font-size: 1.8rem; - margin-bottom: 10px; - } - - .update-time { - font-size: 0.85rem; - padding: 6px 12px; - } - - .topic-item { - padding: 16px; - margin-bottom: 12px; - border-radius: 10px; - } - - .topic-rank { - font-size: 1.1rem; - margin-right: 14px; - min-width: 32px; - width: 32px; - height: 32px; - } - - .topic-title { - font-size: 1rem; - line-height: 1.5; - margin-bottom: 6px; - } - - .topic-cover { - width: 90px; - height: 65px; - } - - footer { - margin-top: 24px; - padding-top: 16px; - font-size: 0.85rem; - } -} - -@media (max-width: 480px) { - .container { - margin: 8px auto; - padding: 14px; - } - - header h1 { - font-size: 1.6rem; - } - - .topic-item { - padding: 14px; - margin-bottom: 10px; - } - - .topic-rank { - font-size: 1rem; - margin-right: 12px; - min-width: 30px; - width: 30px; - height: 30px; - } - - .topic-title { - font-size: 0.95rem; - } - - .topic-cover { - width: 80px; - height: 60px; - } -} - -/* 减少动画以节省电池 */ -@media (prefers-reduced-motion: reduce) { - .modern-gradient, - .modern-gradient::before { - animation: none; - } - - .modern-gradient { - background: linear-gradient( - 135deg, - rgba(64, 169, 255, 0.3) 0%, - rgba(255, 175, 64, 0.2) 50%, - rgba(255, 122, 69, 0.25) 100% - ); - } -} \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/知乎热门话题/img/zhihu-logo.svg b/frontend/60sapi/热搜榜单/知乎热门话题/img/zhihu-logo.svg deleted file mode 100755 index 9f66920b..00000000 --- a/frontend/60sapi/热搜榜单/知乎热门话题/img/zhihu-logo.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/知乎热门话题/index.html b/frontend/60sapi/热搜榜单/知乎热门话题/index.html deleted file mode 100755 index 82c7302d..00000000 --- a/frontend/60sapi/热搜榜单/知乎热门话题/index.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - 知乎热门话题 - - - - -
    -
    -
    - -
    -
    -

    知乎热门话题

    -
    -
    - -
    -
    -
    加载中...
    -
    -
    - -
    -

    数据来源于知乎热门话题

    -
    -
    - - - - \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/知乎热门话题/js/main.js b/frontend/60sapi/热搜榜单/知乎热门话题/js/main.js deleted file mode 100755 index 29c3c2d9..00000000 --- a/frontend/60sapi/热搜榜单/知乎热门话题/js/main.js +++ /dev/null @@ -1,159 +0,0 @@ -// API接口列表 -const API_ENDPOINTS = [ - "https://60s.api.shumengya.top/v2/zhihu", -]; - -// 当前使用的API索引 -let currentApiIndex = 0; - -// DOM元素 -const topicListElement = document.getElementById('topicList'); -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 formatNumber(num) { - if (num >= 10000) { - return (num / 10000).toFixed(1) + '万'; - } - return num.toString(); -} - -// 渲染话题列表 -function renderTopicList(data) { - topicListElement.innerHTML = ''; - - data.forEach((item, index) => { - const topicItem = document.createElement('div'); - topicItem.className = 'topic-item'; - - const rankClass = index < 3 ? `top-${index + 1}` : ''; - - // 处理封面图片 - const coverImg = item.cover ? - `话题封面` : ''; - - // 判断文本内容长度,决定图片位置 - // 如果detail存在且长度较长,或者没有detail但标题较长,则图片放在下方 - const detailLength = item.detail ? item.detail.length : 0; - const titleLength = item.title ? item.title.length : 0; - const isLongContent = detailLength > 100 || (detailLength === 0 && titleLength > 30); - - // 根据内容长度决定布局类名 - const layoutClass = isLongContent ? 'long-content' : 'short-content'; - - topicItem.innerHTML = ` -
    -
    ${index + 1}
    -
    - 🔥 ${item.title} - ${item.detail ? `
    ${item.detail}
    ` : ''} -
    - ${item.hot_value_desc ? `
    🔥 ${item.hot_value_desc}
    ` : ''} - ${item.answer_cnt ? `
    💬 ${formatNumber(item.answer_cnt)} 回答
    ` : ''} - ${item.follower_cnt ? `
    👥 ${formatNumber(item.follower_cnt)} 关注
    ` : ''} -
    -
    - ${coverImg} -
    `; - - topicListElement.appendChild(topicItem); - }); - - // 更新时间 - updateTimeElement.textContent = `更新时间:${formatDate(new Date())}`; -} - -// 显示加载状态 -function showLoading() { - topicListElement.innerHTML = '
    加载中...
    '; -} - -// 显示错误状态 -function showError(message) { - topicListElement.innerHTML = `
    ${message}
    `; -} - -// 获取知乎热门话题数据 -async function fetchZhihuTopics() { - showLoading(); - - try { - const response = await fetch(API_ENDPOINTS[currentApiIndex]); - - if (!response.ok) { - throw new Error(`HTTP ${response.status}: ${response.statusText}`); - } - - const result = await response.json(); - - if (result.code === 200 && result.data && Array.isArray(result.data)) { - if (result.data.length > 0) { - renderTopicList(result.data); - } else { - showError('暂无热门话题数据'); - } - } else { - throw new Error('数据格式错误或无数据'); - } - } catch (error) { - console.error('获取数据失败:', error); - - // 尝试切换到下一个API - const nextApiIndex = (currentApiIndex + 1) % API_ENDPOINTS.length; - - if (nextApiIndex !== 0) { - // 还有其他API可以尝试 - currentApiIndex = nextApiIndex; - showError('获取数据失败,正在尝试其他接口...'); - - // 延迟后重试 - setTimeout(fetchZhihuTopics, 2000); - } else { - // 所有API都尝试过了 - currentApiIndex = 0; - showError('所有接口都无法访问,请稍后再试'); - } - } -} - -// 手动刷新数据 -function refreshData() { - currentApiIndex = 0; // 重置API索引 - fetchZhihuTopics(); -} - -// 页面加载完成后获取数据 -document.addEventListener('DOMContentLoaded', () => { - fetchZhihuTopics(); - - // 每隔5分钟刷新一次数据 - setInterval(fetchZhihuTopics, 5 * 60 * 1000); - - // 添加键盘快捷键支持(按R键刷新) - document.addEventListener('keydown', (event) => { - if (event.key === 'r' || event.key === 'R') { - event.preventDefault(); - refreshData(); - } - }); -}); - -// 页面可见性变化时的处理 -document.addEventListener('visibilitychange', () => { - if (!document.hidden) { - // 页面重新可见时刷新数据 - refreshData(); - } -}); \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/知乎热门话题/接口集合.json b/frontend/60sapi/热搜榜单/知乎热门话题/接口集合.json deleted file mode 100755 index 547b2771..00000000 --- a/frontend/60sapi/热搜榜单/知乎热门话题/接口集合.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "https://60s.api.shumengya.top" -] diff --git a/frontend/60sapi/热搜榜单/知乎热门话题/返回接口.json b/frontend/60sapi/热搜榜单/知乎热门话题/返回接口.json deleted file mode 100755 index a9acef11..00000000 --- a/frontend/60sapi/热搜榜单/知乎热门话题/返回接口.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "code": 200, - "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", - "data": [ - { - "title": "你是什么时候意识到抗日战争很艰难的?", - "detail": "就不像抗日神剧", - "cover": "https://picx.zhimg.com/v2-a07a53b2e23887c7a2440cc3f1984122.png", - "hot_value_desc": "1311 万热度", - "answer_cnt": 739, - "follower_cnt": 1739, - "comment_cnt": 0, - "created_at": 1622774952000, - "created": "2021/06/04 10:49:12", - "link": "https://api.zhihu.com/questions/463076881" - }, - { - "title": "为什么中国在很多领域都要求自主研发?", - "detail": "中国在很多领域都要求自主研发,似乎确认很多东西都有个中国版本,真有这个必要吗?", - "cover": "https://pic3.zhimg.com/80/v2-bb4dfa56f138980078da003df436e661_hd.png", - "hot_value_desc": "816 万热度", - "answer_cnt": 2476, - "follower_cnt": 12545, - "comment_cnt": 0, - "created_at": 1352205751000, - "created": "2012/11/06 20:42:31", - "link": "https://api.zhihu.com/questions/20579464" - } - ] -} \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/网易云榜单/css/background.css b/frontend/60sapi/热搜榜单/网易云榜单/css/background.css deleted file mode 100755 index f67a1aeb..00000000 --- a/frontend/60sapi/热搜榜单/网易云榜单/css/background.css +++ /dev/null @@ -1,128 +0,0 @@ -/* 网易云音乐特色背景样式 */ -body { - background: linear-gradient(135deg, #2b2b2b 0%, #1e1e1e 50%, #2b2b2b 100%); - background-size: 400% 400%; - animation: gradientShift 15s ease infinite; - position: relative; - color: #fff; -} - -/* 背景渐变动画 */ -@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(236, 65, 65, 0.15) 0%, transparent 50%), - radial-gradient(circle at 80% 20%, rgba(236, 65, 65, 0.1) 0%, transparent 50%), - radial-gradient(circle at 40% 40%, rgba(236, 65, 65, 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(236, 65, 65, 0.4), transparent), - radial-gradient(2px 2px at 40px 70px, rgba(236, 65, 65, 0.3), transparent), - radial-gradient(1px 1px at 90px 40px, rgba(236, 65, 65, 0.4), transparent), - radial-gradient(1px 1px at 130px 80px, rgba(236, 65, 65, 0.3), transparent), - radial-gradient(2px 2px at 160px 30px, rgba(236, 65, 65, 0.4), 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); - } -} - -/* 音符装饰 */ -.music-note { - position: absolute; - font-size: 24px; - color: rgba(236, 65, 65, 0.3); - animation: floatNote 15s linear infinite; - z-index: -1; -} - -@keyframes floatNote { - 0% { - transform: translateY(0) rotate(0deg); - opacity: 0; - } - 10% { - opacity: 0.8; - } - 90% { - opacity: 0.8; - } - 100% { - transform: translateY(-100vh) rotate(360deg); - opacity: 0; - } -} - -/* 响应式背景调整 */ -@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, #2b2b2b 0%, #1e1e1e 50%, #2b2b2b 100%); - } - - body::after { - animation: none; - } - - .music-note { - animation: none; - display: none; - } -} \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/网易云榜单/css/responsive.css b/frontend/60sapi/热搜榜单/网易云榜单/css/responsive.css deleted file mode 100755 index ada3cef4..00000000 --- a/frontend/60sapi/热搜榜单/网易云榜单/css/responsive.css +++ /dev/null @@ -1,194 +0,0 @@ -/* 响应式样式 - 适配不同设备 */ - -/* 基础样式 - 移动设备优先 */ -.container { - width: 95%; - padding: 15px; - margin: 10px auto; -} - -header h1 { - font-size: 1.5rem; -} - -.update-time { - font-size: 0.8rem; - padding: 6px 12px; -} - -.rank-list { - grid-template-columns: 1fr; - gap: 16px; - margin-top: 15px; -} - -.rank-item { - border-radius: 10px; -} - -.rank-cover { - height: 160px; -} - -.rank-info { - padding: 12px; -} - -.rank-name { - font-size: 1rem; - margin-bottom: 6px; -} - -.rank-desc { - font-size: 0.85rem; - margin-bottom: 10px; - -webkit-line-clamp: 2; -} - -.rank-meta { - font-size: 0.75rem; - margin-bottom: 10px; -} - -.rank-link { - padding: 6px 14px; - font-size: 0.85rem; -} - -/* 平板设备 */ -@media screen and (min-width: 768px) { - .container { - width: 90%; - padding: 20px; - margin: 15px auto; - } - - header h1 { - font-size: 1.8rem; - } - - .update-time { - font-size: 0.85rem; - padding: 7px 14px; - } - - .rank-list { - grid-template-columns: repeat(2, 1fr); - gap: 20px; - margin-top: 20px; - } - - .rank-cover { - height: 170px; - } - - .rank-info { - padding: 15px; - } - - .rank-name { - font-size: 1.1rem; - margin-bottom: 8px; - } - - .rank-desc { - font-size: 0.9rem; - margin-bottom: 12px; - -webkit-line-clamp: 3; - } - - .rank-meta { - font-size: 0.8rem; - } - - .rank-link { - padding: 7px 16px; - font-size: 0.9rem; - } - - .loading-spinner { - width: 60px; - height: 60px; - } -} - -/* 桌面设备 */ -@media screen and (min-width: 1024px) { - .container { - width: 85%; - max-width: 1200px; - margin: 20px auto; - } - - header h1 { - font-size: 2.2rem; - } - - .update-time { - font-size: 0.9rem; - padding: 8px 16px; - } - - .rank-list { - grid-template-columns: repeat(3, 1fr); - gap: 24px; - margin-top: 25px; - } - - .rank-cover { - height: 180px; - } - - .rank-info { - padding: 18px; - } - - .rank-name { - font-size: 1.2rem; - margin-bottom: 10px; - } - - .rank-desc { - font-size: 0.95rem; - margin-bottom: 15px; - } - - .rank-meta { - font-size: 0.85rem; - margin-bottom: 15px; - } - - .rank-link { - padding: 8px 18px; - font-size: 0.95rem; - } -} - -/* 大屏幕设备 */ -@media screen and (min-width: 1440px) { - .container { - max-width: 1400px; - } - - .rank-list { - grid-template-columns: repeat(4, 1fr); - gap: 30px; - } - - .rank-cover { - height: 200px; - } - - .rank-name { - font-size: 1.25rem; - } - - .rank-desc { - font-size: 1rem; - } - - .rank-link { - padding: 10px 20px; - font-size: 1rem; - } -} \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/网易云榜单/css/style.css b/frontend/60sapi/热搜榜单/网易云榜单/css/style.css deleted file mode 100755 index 72af5361..00000000 --- a/frontend/60sapi/热搜榜单/网易云榜单/css/style.css +++ /dev/null @@ -1,474 +0,0 @@ -/* 背景样式 */ -.background-container { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: -1; - overflow: hidden; - background-color: #f8f9fa; -} - -.modern-gradient { - position: absolute; - top: -50%; - left: -50%; - width: 200%; - height: 200%; - background: linear-gradient( - 135deg, - rgba(64, 169, 255, 0.4) 0%, - rgba(120, 192, 255, 0.3) 25%, - rgba(255, 175, 64, 0.2) 50%, - rgba(255, 140, 50, 0.3) 75%, - rgba(255, 122, 69, 0.4) 100% - ); - animation: gradient-flow 20s ease-in-out infinite; - border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%; -} - -.modern-gradient::before { - content: ''; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: radial-gradient( - circle at 30% 70%, - rgba(64, 169, 255, 0.5) 0%, - transparent 50% - ), radial-gradient( - circle at 70% 30%, - rgba(255, 140, 50, 0.4) 0%, - transparent 50% - ); - animation: pulse-effect 15s ease-in-out infinite alternate; - border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%; -} - -@keyframes gradient-flow { - 0%, 100% { - transform: rotate(0deg) scale(1); - opacity: 0.8; - } - 25% { - transform: rotate(90deg) scale(1.1); - opacity: 0.6; - } - 50% { - transform: rotate(180deg) scale(0.9); - opacity: 0.9; - } - 75% { - transform: rotate(270deg) scale(1.05); - opacity: 0.7; - } -} - -@keyframes pulse-effect { - 0% { - transform: scale(1) rotate(0deg); - opacity: 0.5; - } - 50% { - transform: scale(1.2) rotate(180deg); - opacity: 0.8; - } - 100% { - transform: scale(1) rotate(360deg); - opacity: 0.6; - } -} - -/* 主样式 */ -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -body { - font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif; - color: #333; - background-color: #f8f9fa; - position: relative; - min-height: 100vh; - overflow-x: hidden; - line-height: 1.6; -} - -.container { - max-width: 800px; - margin: 0 auto; - padding: 24px; - position: relative; - z-index: 1; - background-color: rgba(255, 255, 255, 0.85); - border-radius: 16px; - box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08); - backdrop-filter: blur(10px); - position: relative; -} - -header { - text-align: center; - margin-bottom: 28px; - padding-bottom: 20px; - border-bottom: 1px solid rgba(0, 0, 0, 0.06); -} - -header h1 { - background: linear-gradient(135deg, #4096ff, #ff7a45); - -webkit-background-clip: text; - background-clip: text; - color: transparent; - margin-bottom: 14px; - font-size: 2.4rem; - font-weight: 700; - letter-spacing: -0.5px; -} - -.update-time { - color: #666; - font-size: 0.9rem; - background-color: rgba(0, 0, 0, 0.03); - padding: 8px 16px; - border-radius: 24px; - display: inline-block; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04); -} - -.rank-list { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); - gap: 24px; - margin-top: 20px; -} - -.rank-item { - background-color: white; - border-radius: 12px; - box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08); - overflow: hidden; - transition: all 0.3s ease; - display: flex; - flex-direction: column; - border: 1px solid rgba(0, 0, 0, 0.05); -} - -.rank-item:hover { - transform: translateY(-5px); - box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12); - border-color: rgba(236, 65, 65, 0.3); -} - -.rank-cover { - position: relative; - height: 180px; - overflow: hidden; -} - -.rank-cover img { - width: 100%; - height: 100%; - object-fit: cover; - transition: transform 0.5s ease; -} - -.rank-item:hover .rank-cover img { - transform: scale(1.05); -} - -.rank-update { - position: absolute; - bottom: 0; - right: 0; - background: rgba(236, 65, 65, 0.8); - color: white; - padding: 4px 10px; - font-size: 0.8rem; - border-top-left-radius: 8px; -} - -.rank-info { - padding: 16px; - flex: 1; - display: flex; - flex-direction: column; -} - -.rank-name { - font-size: 1.2rem; - font-weight: 600; - margin-bottom: 8px; - color: #333; -} - -.rank-desc { - font-size: 0.9rem; - color: #666; - margin-bottom: 12px; - display: -webkit-box; - -webkit-line-clamp: 3; - -webkit-box-orient: vertical; - overflow: hidden; - flex: 1; -} - -.rank-meta { - font-size: 0.8rem; - color: #999; - margin-bottom: 12px; -} - -.rank-link { - display: inline-block; - background: linear-gradient(135deg, #ec4141, #ff7a45); - color: white; - text-decoration: none; - padding: 8px 16px; - border-radius: 20px; - font-size: 0.9rem; - text-align: center; - transition: all 0.3s ease; - box-shadow: 0 2px 8px rgba(236, 65, 65, 0.3); -} - -.rank-link:hover { - background: linear-gradient(135deg, #d73435, #f06937); - box-shadow: 0 4px 12px rgba(236, 65, 65, 0.4); - transform: translateY(-2px); -} - -.hot-title { - font-size: 1.15rem; - margin-bottom: 8px; - color: #333; - text-decoration: none; - display: block; - line-height: 1.5; - font-weight: 500; - transition: color 0.2s ease; -} - -.hot-title:hover { - color: #4096ff; - text-decoration: none; -} - -.loading { - text-align: center; - padding: 40px; - color: #666; - font-size: 1.1rem; -} - -.loading-spinner { - display: inline-block; - width: 50px; - height: 50px; - border: 3px solid rgba(236, 65, 65, 0.3); - border-radius: 50%; - border-top-color: #ec4141; - animation: spin 1s ease-in-out infinite; - margin-bottom: 16px; -} - -@keyframes spin { - to { transform: rotate(360deg); } -} - -.error-message { - text-align: center; - padding: 40px; - color: #ff4d4f; - font-size: 1.1rem; -} - -.retry-button { - background: #ec4141; - color: white; - border: none; - padding: 8px 20px; - border-radius: 20px; - font-size: 0.9rem; - margin-top: 16px; - cursor: pointer; - transition: all 0.3s ease; -} - -.retry-button:hover { - background: #d73435; - box-shadow: 0 2px 8px rgba(236, 65, 65, 0.4); -} - -footer { - text-align: center; - margin-top: 30px; - padding-top: 20px; - border-top: 1px solid rgba(0, 0, 0, 0.06); - color: #666; - font-size: 0.9rem; -} - -/* 音符装饰样式 */ -.music-note { - position: fixed; - font-size: 24px; - color: rgba(236, 65, 65, 0.6); - z-index: 0; - pointer-events: none; - animation: floatNote 20s linear infinite; - text-shadow: 0 0 5px rgba(255, 255, 255, 0.7); -} - -@keyframes floatNote { - 0% { - transform: translateY(0) rotate(0deg); - opacity: 0.7; - } - 50% { - transform: translateY(-100px) rotate(180deg); - opacity: 0.9; - } - 100% { - transform: translateY(-200px) rotate(360deg); - opacity: 0; - } -} - -/* 响应式设计 */ -@media (max-width: 1024px) and (min-width: 768px) { - .container { - max-width: 90%; - padding: 20px; - } - - header h1 { - font-size: 2.2rem; - } - - .hot-item { - padding: 18px; - } - - .hot-title { - font-size: 1.1rem; - } - - .music-note { - font-size: 22px; - } -} - -@media (max-width: 768px) { - body { - background-color: #f8f9fa; - } - - .container { - max-width: 95%; - margin: 12px auto; - padding: 16px; - border-radius: 12px; - } - - header { - margin-bottom: 20px; - padding-bottom: 16px; - } - - header h1 { - font-size: 1.8rem; - margin-bottom: 10px; - } - - .update-time { - font-size: 0.85rem; - padding: 6px 12px; - } - - .hot-item { - padding: 16px; - margin-bottom: 12px; - border-radius: 10px; - flex-direction: row; - align-items: flex-start; - } - - .hot-rank { - font-size: 1.1rem; - margin-right: 14px; - min-width: 32px; - width: 32px; - height: 32px; - margin-top: 2px; - } - - .hot-title { - font-size: 1rem; - line-height: 1.5; - margin-bottom: 6px; - } - - footer { - margin-top: 24px; - padding-top: 16px; - font-size: 0.85rem; - } - - .music-note { - font-size: 20px; - } -} - -@media (max-width: 480px) { - .container { - margin: 8px auto; - padding: 14px; - } - - header h1 { - font-size: 1.6rem; - } - - .hot-item { - padding: 14px; - margin-bottom: 10px; - } - - .hot-rank { - font-size: 1rem; - margin-right: 12px; - min-width: 30px; - width: 30px; - height: 30px; - } - - .hot-title { - font-size: 0.95rem; - } - - .music-note { - font-size: 16px; - } -} - -/* 减少动画以节省电池 */ -@media (prefers-reduced-motion: reduce) { - .modern-gradient, - .modern-gradient::before { - animation: none; - } - - .modern-gradient { - background: linear-gradient( - 135deg, - rgba(64, 169, 255, 0.3) 0%, - rgba(255, 175, 64, 0.2) 50%, - rgba(255, 122, 69, 0.25) 100% - ); - } -} \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/网易云榜单/index.html b/frontend/60sapi/热搜榜单/网易云榜单/index.html deleted file mode 100755 index 7f3d7ae5..00000000 --- a/frontend/60sapi/热搜榜单/网易云榜单/index.html +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - 网易云音乐榜单 - InfoGenie - - - - - - - -
    -
    -
    - - -
    - -
    -
    -

    网易云音乐榜单

    -
    加载中...
    -
    - -
    -
    -
    -

    正在加载榜单数据...

    -
    - - - - -
    - -
    -

    数据来源:网易云音乐官方API

    -

    © 2024 InfoGenie - 网易云音乐榜单

    -
    -
    - - - - \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/网易云榜单/js/app.js b/frontend/60sapi/热搜榜单/网易云榜单/js/app.js deleted file mode 100755 index 739fb559..00000000 --- a/frontend/60sapi/热搜榜单/网易云榜单/js/app.js +++ /dev/null @@ -1,252 +0,0 @@ -/** - * 网易云音乐榜单 - 主应用脚本 - * 功能:获取API数据、渲染榜单、处理错误、自动切换API接口 - */ - -// 全局变量 -const apiUrls = []; -let currentApiIndex = 0; -let rankData = null; - -// DOM元素 -const loadingElement = document.getElementById('loading'); -const errorElement = document.getElementById('error-message'); -const rankListElement = document.getElementById('rank-list'); -const updateTimeElement = document.getElementById('update-time'); -const retryButton = document.getElementById('retry-button'); - -// 初始化函数 -async function init() { - try { - // 获取API接口列表 - await loadApiUrls(); - - // 获取榜单数据 - await fetchRankData(); - - // 添加音符装饰 - createMusicNotes(); - } catch (error) { - console.error('初始化失败:', error); - showError(); - } -} - -// 加载API接口列表 -async function loadApiUrls() { - try { - const response = await fetch('./接口集合.json'); - if (!response.ok) { - throw new Error('无法加载API接口列表'); - } - const data = await response.json(); - if (Array.isArray(data) && data.length > 0) { - apiUrls.push(...data); - console.log('已加载API接口列表:', apiUrls); - } else { - throw new Error('API接口列表为空'); - } - } catch (error) { - console.error('加载API接口列表失败:', error); - // 使用默认API - apiUrls.push('https://60s.api.shumengya.top/v2/ncm-rank'); - } -} - -// 获取榜单数据 -async function fetchRankData() { - showLoading(); - - // 如果没有API接口,显示错误 - if (apiUrls.length === 0) { - throw new Error('没有可用的API接口'); - } - - try { - const apiUrl = apiUrls[currentApiIndex]; - const response = await fetch(apiUrl); - - if (!response.ok) { - throw new Error(`API请求失败: ${response.status}`); - } - - const data = await response.json(); - - if (data.code === 200 && data.data && Array.isArray(data.data)) { - rankData = data; - renderRankList(data.data); - updateLastUpdateTime(data); - hideLoading(); - } else { - throw new Error('API返回数据格式错误'); - } - } catch (error) { - console.error('获取榜单数据失败:', error); - // 尝试切换到下一个API - if (tryNextApi()) { - return fetchRankData(); - } else { - showError(); - } - } -} - -// 尝试切换到下一个API -function tryNextApi() { - if (currentApiIndex < apiUrls.length - 1) { - currentApiIndex++; - console.log(`切换到下一个API: ${apiUrls[currentApiIndex]}`); - return true; - } - return false; -} - -// 渲染榜单列表 -function renderRankList(ranks) { - if (!Array.isArray(ranks) || ranks.length === 0) { - showError('没有榜单数据'); - return; - } - - rankListElement.innerHTML = ''; - - ranks.forEach(rank => { - const rankItem = document.createElement('div'); - rankItem.className = 'rank-item'; - - // 构建榜单项HTML - rankItem.innerHTML = ` -
    - ${rank.name} -
    ${rank.update_frequency || '定期更新'}
    -
    -
    -

    ${rank.name}

    -

    ${rank.description || '暂无描述'}

    -
    - 更新: ${formatDate(rank.updated)} -
    - 查看详情 -
    - `; - - rankListElement.appendChild(rankItem); - }); - - rankListElement.style.display = 'grid'; -} - -// 更新最后更新时间 -function updateLastUpdateTime(data) { - if (data && data.data && data.data.length > 0) { - const latestRank = data.data.reduce((latest, current) => { - const latestDate = latest.updated_at || 0; - const currentDate = current.updated_at || 0; - return currentDate > latestDate ? current : latest; - }, data.data[0]); - - if (latestRank && latestRank.updated) { - updateTimeElement.textContent = `最近更新: ${formatDate(latestRank.updated)}`; - } else { - updateTimeElement.textContent = '数据已更新'; - } - } -} - -// 格式化日期 -function formatDate(dateStr) { - if (!dateStr) return '未知'; - - try { - const date = new Date(dateStr.replace('2025-', '2024-')); - if (isNaN(date.getTime())) return dateStr; - - return date.toLocaleDateString('zh-CN', { - year: 'numeric', - month: '2-digit', - day: '2-digit', - hour: '2-digit', - minute: '2-digit' - }).replace(/\//g, '-'); - } catch (e) { - return dateStr; - } -} - -// 创建音符装饰 -function createMusicNotes() { - const notesContainer = document.getElementById('music-notes-container'); - const notes = ['♪', '♫', '♬', '♩', '♭', '♮']; - const containerWidth = window.innerWidth; - const containerHeight = window.innerHeight; - - // 清空容器 - notesContainer.innerHTML = ''; - - // 创建15个音符 - for (let i = 0; i < 15; i++) { - const note = document.createElement('div'); - note.className = 'music-note'; - note.textContent = notes[Math.floor(Math.random() * notes.length)]; - - // 随机位置 - const left = Math.random() * containerWidth; - const top = Math.random() * containerHeight; - - // 随机动画延迟 - const delay = Math.random() * 20; - const duration = 15 + Math.random() * 15; - - // 设置样式 - note.style.left = `${left}px`; - note.style.top = `${top}px`; - note.style.animationDelay = `${delay}s`; - note.style.animationDuration = `${duration}s`; - - notesContainer.appendChild(note); - } -} - -// 显示加载中 -function showLoading() { - loadingElement.style.display = 'block'; - errorElement.style.display = 'none'; - rankListElement.style.display = 'none'; -} - -// 隐藏加载中 -function hideLoading() { - loadingElement.style.display = 'none'; -} - -// 显示错误信息 -function showError(message = '加载失败,请稍后再试') { - loadingElement.style.display = 'none'; - errorElement.querySelector('p').textContent = message; - errorElement.style.display = 'block'; -} - -// 重试按钮点击事件 -retryButton.addEventListener('click', () => { - // 重置API索引 - currentApiIndex = 0; - // 重新获取数据 - fetchRankData(); -}); - -// 窗口大小改变时重新创建音符 -window.addEventListener('resize', debounce(createMusicNotes, 300)); - -// 防抖函数 -function debounce(func, wait) { - let timeout; - return function() { - const context = this; - const args = arguments; - clearTimeout(timeout); - timeout = setTimeout(() => func.apply(context, args), wait); - }; -} - -// 页面加载完成后初始化 -document.addEventListener('DOMContentLoaded', init); \ No newline at end of file diff --git a/frontend/60sapi/热搜榜单/网易云榜单/接口集合.json b/frontend/60sapi/热搜榜单/网易云榜单/接口集合.json deleted file mode 100755 index 1d87168c..00000000 --- a/frontend/60sapi/热搜榜单/网易云榜单/接口集合.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "https://60s.api.shumengya.top/v2/ncm-rank" -] diff --git a/frontend/60sapi/热搜榜单/网易云榜单/返回接口.json b/frontend/60sapi/热搜榜单/网易云榜单/返回接口.json deleted file mode 100755 index a4cd0831..00000000 --- a/frontend/60sapi/热搜榜单/网易云榜单/返回接口.json +++ /dev/null @@ -1,750 +0,0 @@ -{ - "code": 200, - "message": "获取成功。数据来自官方/权威源头,以确保稳定与实时。开源地址 https://github.com/vikiboss/60s,反馈群 595941841", - "data": [ - { - "id": 19723756, - "name": "飙升榜", - "description": "云音乐中每天热度上升最快的100首单曲,每日更新。", - "cover": "https://p2.music.126.net/rIi7Qzy2i2Y_1QD7cd0MYA==/109951170048506929.jpg", - "update_frequency": "更新78首", - "updated": "2025-09-05 08:24:41", - "updated_at": 1757031881385, - "created": "2014-06-30 15:58:56", - "created_at": 1404115136883, - "link": "https://music.163.com/#/discover/toplist?id=19723756" - }, - { - "id": 3779629, - "name": "新歌榜", - "description": "云音乐新歌榜:云音乐用户一周内收听所有新歌(一月内最新发行) 官方TOP排行榜,每天更新。", - "cover": "https://p2.music.126.net/5guhqPBTcIrrhLBotgaT6w==/109951170048511751.jpg", - "update_frequency": "刚刚更新", - "updated": "2025-09-05 08:24:50", - "updated_at": 1757031890587, - "created": "2013-09-09 18: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://p2.music.126.net/BaP9nrocNTL3gGThysv4eQ==/109951170091896587.jpg", - "update_frequency": "每周四更新", - "updated": "2025-09-04 10:54:42", - "updated_at": 1756954482653, - "created": "2013-07-25 14:05:25", - "created_at": 1374732325894, - "link": "https://music.163.com/#/discover/toplist?id=2884035" - }, - { - "id": 3778678, - "name": "热歌榜", - "description": "云音乐热歌榜:云音乐用户一周内收听所有线上歌曲官方TOP排行榜,每日更新。", - "cover": "https://p2.music.126.net/0SUEG8yDACfx0Bw2MYFv4Q==/109951170048519512.jpg", - "update_frequency": "更新14首", - "updated": "2025-09-05 08:25:03", - "updated_at": 1757031903733, - "created": "2013-09-09 18: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://p2.music.126.net/GgHbgDfGXHpE2YTchU7IvA==/109951171510498108.jpg", - "update_frequency": "每周五更新", - "updated": "2025-08-29 10:19:58", - "updated_at": 1756433998618, - "created": "2017-11-10 13:06:29", - "created_at": 1510290389440, - "link": "https://music.163.com/#/discover/toplist?id=991319590" - }, - { - "id": 71384707, - "name": "网易云古典榜", - "description": "网易云用户一周内收听所有古典音乐官方TOP排行榜,每周四更新。", - "cover": "https://p2.music.126.net/urByD_AmfBDBrs7fA9-O8A==/109951167976973225.jpg", - "update_frequency": "每周四更新", - "updated": "2025-09-04 10:52:54", - "updated_at": 1756954374913, - "created": "2015-05-07 11:22:00", - "created_at": 1430968920537, - "link": "https://music.163.com/#/discover/toplist?id=71384707" - }, - { - "id": 1978921795, - "name": "网易云电音榜", - "description": "网易云用户一周内收听电子音乐官方TOP排行榜,每周五更新。喜力星电音,用先锋电音带你解锁全新维度和体验!", - "cover": "https://p2.music.126.net/hXGObvXfsGtFjFvRhOYAkA==/109951170091888741.jpg", - "update_frequency": "每周五更新", - "updated": "2025-08-29 12:00:01", - "updated_at": 1756440001367, - "created": "2017-11-16 17:47:12", - "created_at": 1510825632233, - "link": "https://music.163.com/#/discover/toplist?id=1978921795" - }, - { - "id": 14028249541, - "name": "网易云全球说唱榜", - "description": "想聆听世界的说唱节奏?全球说唱榜每周五更新,聚焦华语地区以外的优秀说唱作品。根据云音乐用户每周播放热度数据,按照综合数据排名取前 50 名。", - "cover": "https://p2.music.126.net/0hhFjP6WyIjHYDXKW5E7BA==/109951171535150782.jpg", - "update_frequency": "每周五更新", - "updated": "2025-08-29 11:51:16", - "updated_at": 1756439476712, - "created": "2025-07-24 14:09:26", - "created_at": 1753337366883, - "link": "https://music.163.com/#/discover/toplist?id=14028249541" - }, - { - "id": 13372522766, - "name": "潮流风向榜", - "description": "精心挑选云音乐极具声量的音乐作品,呈现歌曲真实热度趋势,榜单每日更新。", - "cover": "https://p2.music.126.net/dIKA5e7jCncz2Br1Toxgaw==/109951170621574552.jpg", - "update_frequency": "每天更新", - "updated": "2025-09-04 12:05:58", - "updated_at": 1756958758114, - "created": "2025-02-26 14:01:33", - "created_at": 1740549693794, - "link": "https://music.163.com/#/discover/toplist?id=13372522766" - }, - { - "id": 12911403728, - "name": "音乐合伙人推荐榜", - "description": "音乐合伙人近一个月内推荐过的歌曲官方TOP排行榜,每周一更新。 跟随音乐合伙人的步伐,一起发现那些隐藏的音乐瑰宝。", - "cover": "https://p2.music.126.net/s6ITpmGjKbyDpi7DPkqd2w==/109951170187827373.jpg", - "update_frequency": "每周一更新", - "updated": "2025-09-01 12:06:04", - "updated_at": 1756699564013, - "created": "2024-11-25 15:14:30", - "created_at": 1732518870190, - "link": "https://music.163.com/#/discover/toplist?id=12911403728" - }, - { - "id": 12911589513, - "name": "音乐合伙人热歌榜", - "description": "音乐合伙人近一周评定过的高分热歌官方TOP排行榜,每周一更新。 跟随音乐合伙人的步伐,一起发现那些隐藏的音乐瑰宝。", - "cover": "https://p2.music.126.net/RgYxQmB-ZUjkMRo2N1jWnQ==/109951170187823494.jpg", - "update_frequency": "每周一更新", - "updated": "2025-09-01 12:06:01", - "updated_at": 1756699561725, - "created": "2024-11-25 15:13:46", - "created_at": 1732518826543, - "link": "https://music.163.com/#/discover/toplist?id=12911589513" - }, - { - "id": 12911619970, - "name": "音乐合伙人留名榜", - "description": "音乐合伙人近一个月内留名过的所有歌曲官方TOP排行榜,每周一更新。 跟随音乐合伙人的步伐,一起发现那些隐藏的音乐瑰宝。", - "cover": "https://p2.music.126.net/aJJzGIxhkVaD7dX0XBNUnw==/109951170187831145.jpg", - "update_frequency": "每周一更新", - "updated": "2025-09-01 12:05:49", - "updated_at": 1756699549550, - "created": "2024-11-25 15:12:50", - "created_at": 1732518770868, - "link": "https://music.163.com/#/discover/toplist?id=12911619970" - }, - { - "id": 12911379734, - "name": "音乐合伙人高分新歌榜", - "description": "音乐合伙人近期评定过的所有新歌(一个月内最新发行)官方TOP排行榜,每周一更新。 跟随音乐合伙人的步伐,一起发现那些隐藏的音乐瑰宝。", - "cover": "https://p2.music.126.net/bfk15bvanhdPFU7yjPFgWA==/109951170187832038.jpg", - "update_frequency": "每周一更新", - "updated": "2025-09-01 12:05:54", - "updated_at": 1756699554077, - "created": "2024-11-25 15:11:53", - "created_at": 1732518713161, - "link": "https://music.163.com/#/discover/toplist?id=12911379734" - }, - { - "id": 12768855486, - "name": "音乐合伙人高分榜", - "description": "音乐合伙人的高分歌曲官方榜单,收录近半年来获得音乐合伙人高分推荐的TOP100首歌曲,每日更新。跟随音乐合伙人的步伐,一起发现那些隐藏的音乐瑰宝。", - "cover": "https://p2.music.126.net/fPP5T0Z8Ac15qNvRTcHa6g==/109951170074028970.jpg", - "update_frequency": "每天更新", - "updated": "2025-09-04 12:05:49", - "updated_at": 1756958749724, - "created": "2024-10-25 11: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://p2.music.126.net/qo6-o9n5AhMjNyejev38-A==/109951169743111905.jpg", - "update_frequency": "每周四更新", - "updated": "2025-09-04 18:05:01", - "updated_at": 1756980301317, - "created": "2021-01-08 14:30:24", - "created_at": 1610087424470, - "link": "https://music.163.com/#/discover/toplist?id=5453912201" - }, - { - "id": 71385702, - "name": "网易云ACG榜", - "description": "网易云用户一周内收听所有ACG音乐官方TOP排行榜,每周四更新。", - "cover": "https://p2.music.126.net/na1kEeCS1iZEkzOrs9r_9g==/109951167976973667.jpg", - "update_frequency": "每周四更新", - "updated": "2025-09-04 10:19:13", - "updated_at": 1756952353409, - "created": "2015-05-07 11:22:15", - "created_at": 1430968935040, - "link": "https://music.163.com/#/discover/toplist?id=71385702" - }, - { - "id": 745956260, - "name": "网易云韩语榜", - "description": "网易云用户一周内收听所有韩语歌曲官方TOP排行榜,每周四更新。", - "cover": "https://p2.music.126.net/5oN9YaFznwNGXkmi8i2Ytw==/109951167430864741.jpg", - "update_frequency": "每周四更新", - "updated": "2025-09-04 10:30:40", - "updated_at": 1756953040555, - "created": "2017-05-31 11:34:51", - "created_at": 1496201691281, - "link": "https://music.163.com/#/discover/toplist?id=745956260" - }, - { - "id": 180106, - "name": "UK排行榜周榜", - "description": "UK排行榜", - "cover": "https://p2.music.126.net/fhAqiflLy3eU-ldmBQByrg==/109951165613082765.jpg", - "update_frequency": "每天更新", - "updated": "2025-09-01 10:26:53", - "updated_at": 1756693613998, - "created": "2013-02-19 10:09:26", - "created_at": 1361239766844, - "link": "https://music.163.com/#/discover/toplist?id=180106" - }, - { - "id": 60198, - "name": "美国Billboard榜", - "description": "美国Billboard排行榜", - "cover": "https://p2.music.126.net/rwRsVIJHQ68gglhA6TNEYA==/109951165611413732.jpg", - "update_frequency": "每周三更新", - "updated": "2025-09-03 10:40:27", - "updated_at": 1756867227129, - "created": "2013-01-22 10:51:16", - "created_at": 1358823076818, - "link": "https://music.163.com/#/discover/toplist?id=60198" - }, - { - "id": 3812895, - "name": "Beatport全球电子舞曲榜", - "description": "Beatport全球电子舞曲排行榜TOP100(本榜每周三更新)", - "cover": "https://p2.music.126.net/oT-RHuPBJiD7WMoU7WG5Rw==/109951166093489621.jpg", - "update_frequency": "每周三更新", - "updated": "2025-09-03 10:51:47", - "updated_at": 1756867907849, - "created": "2013-09-11 16: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://p2.music.126.net/5wDP78s43ydVTKt62C8OjQ==/109951165613100063.jpg", - "update_frequency": "每周五更新", - "updated": "2021-11-26 17:56:43", - "updated_at": 1637920603975, - "created": "2014-07-18 11:11:33", - "created_at": 1405653093230, - "link": "https://music.163.com/#/discover/toplist?id=21845217" - }, - { - "id": 60131, - "name": "日本Oricon榜", - "description": "日本Oricon数字单曲周榜,每周三更新,欢迎关注。", - "cover": "https://p2.music.126.net/aXUPgImt8hhf4cMUZEjP4g==/109951165611417794.jpg", - "update_frequency": "每天更新", - "updated": "2025-08-29 10:20:10", - "updated_at": 1756434010126, - "created": "2013-01-08 16: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://p2.music.126.net/70_EO_Dc7NT_hhfvsapzcQ==/109951167430862162.jpg", - "update_frequency": "每周四更新", - "updated": "2025-09-04 09:44:52", - "updated_at": 1756950292193, - "created": "2019-05-22 10: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://p2.music.126.net/0lPWpI9Ejn1OiW2LSbg-qw==/109951167430863224.jpg", - "update_frequency": "每天更新", - "updated": "2025-09-04 09:44:27", - "updated_at": 1756950267625, - "created": "2019-05-22 10: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://p2.music.126.net/-fyzrPWd06FfWl_0JDAxMQ==/109951165613108584.jpg", - "update_frequency": "每周五更新", - "updated": "2025-08-29 10:20:26", - "updated_at": 1756434026143, - "created": "2014-09-04 18:03:33", - "created_at": 1409825013948, - "link": "https://music.163.com/#/discover/toplist?id=27135204" - }, - { - "id": 3001835560, - "name": "网易云ACG动画榜", - "description": "网易云中每天热度上升最快的100首ACG动画单曲,每日更新。", - "cover": "https://p2.music.126.net/SkGlKQ6acixthb77VlD9eQ==/109951164432300406.jpg", - "update_frequency": "每天更新", - "updated": "2025-09-04 12:05:09", - "updated_at": 1756958709531, - "created": "2019-09-27 10:03:58", - "created_at": 1569549838610, - "link": "https://music.163.com/#/discover/toplist?id=3001835560" - }, - { - "id": 3001795926, - "name": "网易云ACG游戏榜", - "description": "网易云中每天热度上升最快的100首ACG游戏单曲,每日更新。", - "cover": "https://p2.music.126.net/hivOOHMwEmnn9s_6rgZwEQ==/109951164432303700.jpg", - "update_frequency": "每天更新", - "updated": "2025-09-04 12:05:17", - "updated_at": 1756958717981, - "created": "2019-09-27 10:04:56", - "created_at": 1569549896656, - "link": "https://music.163.com/#/discover/toplist?id=3001795926" - }, - { - "id": 3001890046, - "name": "网易云ACG VOCALOID榜", - "description": "", - "cover": "https://p2.music.126.net/Ag7RyRCYiINcd9EtRXf6xA==/109951164432303690.jpg", - "update_frequency": "每天更新", - "updated": "2025-09-04 12:05:25", - "updated_at": 1756958725790, - "created": "2019-09-27 10:05:25", - "created_at": 1569549925472, - "link": "https://music.163.com/#/discover/toplist?id=3001890046" - }, - { - "id": 5059644681, - "name": "网易云日语榜", - "description": "网易云用户一周内收听所有日语歌曲官方TOP排行榜,每周二更新。", - "cover": "https://p2.music.126.net/YFBFNI2F-4BveUpv6FKFuw==/109951167430864069.jpg", - "update_frequency": "每周二更新", - "updated": "2025-09-02 10:57:27", - "updated_at": 1756781847266, - "created": "2020-06-11 16:10:00", - "created_at": 1591863000459, - "link": "https://music.163.com/#/discover/toplist?id=5059644681" - }, - { - "id": 5059633707, - "name": "网易云摇滚榜", - "description": "网易云用户一周内收听所有摇滚歌曲官方TOP排行榜,每周五更新。", - "cover": "https://p2.music.126.net/LjkX2hktgFD1NXc3W6w0sA==/109951170048522513.jpg", - "update_frequency": "每周五更新", - "updated": "2025-08-29 17:02:04", - "updated_at": 1756458124397, - "created": "2020-06-11 16:13:33", - "created_at": 1591863213389, - "link": "https://music.163.com/#/discover/toplist?id=5059633707" - }, - { - "id": 5059642708, - "name": "网易云国风榜", - "description": "网易云用户一周内收听所有国风歌曲官方TOP排行榜,每周五更新。", - "cover": "https://p2.music.126.net/kTJC5OBhg8I477X_ZmXyDQ==/109951168539740982.jpg", - "update_frequency": "每周五更新", - "updated": "2025-08-29 09:58:05", - "updated_at": 1756432685431, - "created": "2020-06-11 16:14:18", - "created_at": 1591863258438, - "link": "https://music.163.com/#/discover/toplist?id=5059642708" - }, - { - "id": 5338990334, - "name": "潜力爆款榜", - "description": "全民一起PICK潜力好歌,每周二更新", - "cover": "https://p2.music.126.net/Mi4QPklg1mtbWAfq74tEqQ==/109951165498334721.jpg", - "update_frequency": "每周二更新", - "updated": "2025-09-02 12:05:33", - "updated_at": 1756785933871, - "created": "2020-11-17 14:24:34", - "created_at": 1605594274077, - "link": "https://music.163.com/#/discover/toplist?id=5338990334" - }, - { - "id": 5059661515, - "name": "网易云民谣榜", - "description": "网易云用户一周内收听所有民谣歌曲官方TOP排行榜,每周五更新。", - "cover": "https://p2.music.126.net/Xe9qLTAqtBAWX_hPgFHMyw==/109951170048510929.jpg", - "update_frequency": "每周五更新", - "updated": "2025-08-29 17:00:41", - "updated_at": 1756458041706, - "created": "2020-06-11 16:10:52", - "created_at": 1591863052757, - "link": "https://music.163.com/#/discover/toplist?id=5059661515" - }, - { - "id": 6688069460, - "name": "听歌识曲榜", - "description": "网易云音乐站内歌曲按用户“听歌识曲”次数排列,每周四更新", - "cover": "https://p2.music.126.net/wJVUAiUuykKk7yGbQxDBug==/109951167430857712.jpg", - "update_frequency": "更新24首", - "updated": "2025-09-04 23:35:03", - "updated_at": 1757000103145, - "created": "2021-03-31 16:45:54", - "created_at": 1617180354803, - "link": "https://music.163.com/#/discover/toplist?id=6688069460" - }, - { - "id": 6723173524, - "name": "网络热歌榜", - "description": "网罗一周热门网络歌曲,反映云音乐用户近一周网络热歌收听趋势。每周五更新。", - "cover": "https://p2.music.126.net/_kSxOPqQ5J5etC5DKTFwNA==/109951170048519530.jpg", - "update_frequency": "每周五更新", - "updated": "2025-08-29 11:03:41", - "updated_at": 1756436621202, - "created": "2021-04-22 10:41:46", - "created_at": 1619059306654, - "link": "https://music.163.com/#/discover/toplist?id=6723173524" - }, - { - "id": 6732051320, - "name": "俄语榜", - "description": "网易云音乐用户一周内收听所有俄罗斯语歌曲官方TOP排行榜,每周四更新。", - "cover": "https://p2.music.126.net/HbJ0BK5doY4I4pEMY6-FQw==/109951167430852698.jpg", - "update_frequency": "每周四更新", - "updated": "2025-09-04 10:21:42", - "updated_at": 1756952502045, - "created": "2021-04-28 12:05:12", - "created_at": 1619582712108, - "link": "https://music.163.com/#/discover/toplist?id=6732051320" - }, - { - "id": 6732014811, - "name": "越南语榜", - "description": "网易云音乐用户一周内收听所有越南语歌曲官方TOP排行榜,每周四更新。", - "cover": "https://p2.music.126.net/N-Y5maLGWgrowt3TE6RtSg==/109951167430857045.jpg", - "update_frequency": "每周四更新", - "updated": "2025-09-04 10:28:52", - "updated_at": 1756952932171, - "created": "2021-04-28 12:05:49", - "created_at": 1619582749349, - "link": "https://music.163.com/#/discover/toplist?id=6732014811" - }, - { - "id": 6886768100, - "name": "中文慢摇DJ榜", - "description": "搜索“DJ”,进入慢摇DJ专区,探索更多网络热歌!", - "cover": "https://p2.music.126.net/w_01BfDU012ojxnzLO6tYw==/109951167977358686.jpg", - "update_frequency": "每天更新", - "updated": "2025-09-04 12:00:00", - "updated_at": 1756958400638, - "created": "2021-07-28 18: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://p2.music.126.net/KLVO8PxVZzOoLdWQQNyprA==/109951166327316568.jpg", - "update_frequency": "每周五更新", - "updated": "2025-08-29 17:03:04", - "updated_at": 1756458184216, - "created": "2021-08-27 11:30:02", - "created_at": 1630035002268, - "link": "https://music.163.com/#/discover/toplist?id=6939992364" - }, - { - "id": 7095271308, - "name": "泰语榜", - "description": "网易云音乐用户一周内收听所有泰语歌曲官方TOP排行榜,每周四更新。", - "cover": "https://p2.music.126.net/4W0WBHBgwYlYfRniuyL47A==/109951167430843284.jpg", - "update_frequency": "每周四更新", - "updated": "2025-09-04 10:41:26", - "updated_at": 1756953686280, - "created": "2021-11-29 14: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://p2.music.126.net/yhzlQJCJ9NcT4MvJBG_HgQ==/109951167977014958.jpg", - "update_frequency": "每周四更新", - "updated": "2025-09-04 20:05:00", - "updated_at": 1756987500926, - "created": "2022-03-29 19: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 Rae,Aquamarine", - "cover": "https://p2.music.126.net/u440jFG0N5i06C9ejOeMCQ==/109951171381091309.jpg", - "update_frequency": "每周五更新", - "updated": "2025-06-30 16:17:26", - "updated_at": 1751271446032, - "created": "2022-03-09 11:24:46", - "created_at": 1646796286440, - "link": "https://music.163.com/#/discover/toplist?id=7325478166" - }, - { - "id": 7603212484, - "name": "LOOK直播歌曲榜", - "description": "LOOK直播好歌共赏,专属你的声音聊愈场。榜单选取符合条件且近7日热度最高的前50首歌曲,每周二更新。", - "cover": "https://p1.music.126.net/u-RQC-LyY0aoeseRumJ14A==/109951167977730469.jpg", - "update_frequency": "每周二更新", - "updated": "2024-05-07 21:23:03", - "updated_at": 1715088183913, - "created": "2022-08-23 09:54:56", - "created_at": 1661219696017, - "link": "https://music.163.com/#/discover/toplist?id=7603212484" - }, - { - "id": 7775163417, - "name": "赏音榜", - "description": "云音乐歌曲赏音榜,以让用户鉴赏到更多潜力好歌为目的,以用户对歌曲互动热度为核心,按照综合数据排名取前100名,每日更新", - "cover": "https://p1.music.126.net/m9hQzC-d5wefBipedNPaHg==/109951168178601971.jpg", - "update_frequency": "每天更新", - "updated": "2025-09-04 12:05:36", - "updated_at": 1756958736108, - "created": "2022-11-28 14: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://p1.music.126.net/vjitpkT9nXBCth6tvdDMWg==/109951169743115266.jpg", - "update_frequency": "每天更新", - "updated": "2025-09-04 12:05:37", - "updated_at": 1756958737548, - "created": "2022-12-02 18: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://p1.music.126.net/Ay3mLgQ9weG_c8JjYrD-Bw==/109951169743106495.jpg", - "update_frequency": "每天更新", - "updated": "2025-09-04 12:05:36", - "updated_at": 1756958736684, - "created": "2022-12-02 18: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://p1.music.126.net/R7DtZqNraesnsiaIKvzTHA==/109951169743112799.jpg", - "update_frequency": "每天更新", - "updated": "2025-09-04 12:05:41", - "updated_at": 1756958741914, - "created": "2022-12-02 18:51:43", - "created_at": 1669978303210, - "link": "https://music.163.com/#/discover/toplist?id=7785091694" - }, - { - "id": 8246775932, - "name": "实时热度榜", - "description": "每天9-23点为你精选当下歌曲热度最高的歌曲", - "cover": "https://p1.music.126.net/U7ZbdpWzRdmZVr6Khn_4ag==/109951168673982478.jpg", - "update_frequency": "更新65首", - "updated": "2025-09-05 09:30:07", - "updated_at": 1757035807371, - "created": "2023-03-20 10:39:59", - "created_at": 1679279999154, - "link": "https://music.163.com/#/discover/toplist?id=8246775932" - }, - { - "id": 8537588450, - "name": "喜力®星电音派对潮音榜", - "description": "乐无界,越未来!《星电音联盟》歌曲官方榜单,每周一更新,让云村村民们随时随地躁起高燃派对氛围!喜力®星电音构建狂欢永不停歇的新奇电音宇宙,激活潮流基因,释放先锋灵感,跨维开启奇妙电音之旅!", - "cover": "https://p1.music.126.net/HVu2hGYvzN5XBuvFc_4Bgg==/109951168730309120.jpg", - "update_frequency": "每周五更新", - "updated": "2024-09-16 12:05:30", - "updated_at": 1726459530378, - "created": "2023-07-07 10:48:39", - "created_at": 1688698119437, - "link": "https://music.163.com/#/discover/toplist?id=8537588450" - }, - { - "id": 8661209031, - "name": "乐夏榜", - "description": "听乐夏,上网易云,一头扎进爱音乐的人群! 综艺《乐队的夏天3》官方榜单,每周一更新。和三星折叠屏手机一起畅听《乐队的夏天3》官方榜单,折叠看三星,五代更来劲。", - "cover": "https://p1.music.126.net/RlStCmE97y0xYFk7rS3Zww==/109951168864907822.jpg", - "update_frequency": "每周一更新", - "updated": "2025-09-01 12:05:41", - "updated_at": 1756699541864, - "created": "2023-08-16 17:47:27", - "created_at": 1692179247425, - "link": "https://music.163.com/#/discover/toplist?id=8661209031" - }, - { - "id": 8703179781, - "name": "特斯拉车友爱听榜", - "description": null, - "cover": "https://p1.music.126.net/UL8dhobSa3TR6Wd1JmWe_g==/109951168924385363.jpg", - "update_frequency": "每周一更新", - "updated": "2025-09-01 16:05:08", - "updated_at": 1756713908385, - "created": "2023-08-31 12:29:59", - "created_at": 1693456199735, - "link": "https://music.163.com/#/discover/toplist?id=8703179781" - }, - { - "id": 8703052295, - "name": "理想车友爱听榜", - "description": null, - "cover": "https://p1.music.126.net/U--PWdWupY1ER5cVSjr1jQ==/109951168928365496.jpg", - "update_frequency": "每周一更新", - "updated": "2025-09-01 16:05:09", - "updated_at": 1756713909830, - "created": "2023-08-31 12:38:29", - "created_at": 1693456709598, - "link": "https://music.163.com/#/discover/toplist?id=8703052295" - }, - { - "id": 8702582160, - "name": "比亚迪车友爱听榜", - "description": null, - "cover": "https://p1.music.126.net/S1OG-OLTaofa3HfrHW48kA==/109951168924393585.jpg", - "update_frequency": "每周一更新", - "updated": "2025-09-01 16:05:07", - "updated_at": 1756713907323, - "created": "2023-08-31 12:38:42", - "created_at": 1693456722262, - "link": "https://music.163.com/#/discover/toplist?id=8702582160" - }, - { - "id": 8703220480, - "name": "蔚来车友爱听榜", - "description": null, - "cover": "https://p1.music.126.net/r9kBQNsOro1EAB82Ol51WQ==/109951168924380971.jpg", - "update_frequency": "每周一更新", - "updated": "2025-09-01 16:05:04", - "updated_at": 1756713904286, - "created": "2023-08-31 12:38:56", - "created_at": 1693456736086, - "link": "https://music.163.com/#/discover/toplist?id=8703220480" - }, - { - "id": 8702982391, - "name": "极氪车友爱听榜", - "description": null, - "cover": "https://p1.music.126.net/Cu0RXoKewSPM9Gyc7Cp8jw==/109951168924391596.jpg", - "update_frequency": "每周一更新", - "updated": "2025-09-01 16:05:06", - "updated_at": 1756713906978, - "created": "2023-08-31 12:39:19", - "created_at": 1693456759762, - "link": "https://music.163.com/#/discover/toplist?id=8702982391" - }, - { - "id": 8532443277, - "name": "蛋仔派对听歌榜", - "description": "来自蛋仔岛的热播歌曲速递,网易《蛋仔派对》官方榜单,每周五更新。云村村民们,和蛋仔们一起随歌摇摆吧!", - "cover": "https://p1.music.126.net/TMb0be5QLMZKOFeuOKT4tg==/109951168717283910.jpg", - "update_frequency": "每周五更新", - "updated": "2025-08-29 12:05:43", - "updated_at": 1756440343562, - "created": "2023-07-05 10:32:04", - "created_at": 1688524324879, - "link": "https://music.163.com/#/discover/toplist?id=8532443277" - }, - { - "id": 9651277674, - "name": "AI歌曲榜", - "description": "精心挑选每日最新最热AI生成歌曲,榜单每日更新,一起感受AI的独特魅力吧!", - "cover": "https://p1.music.126.net/M0m6GeZ1Y8Osz9jqxaW8Wg==/109951169462048035.jpg", - "update_frequency": "每天更新", - "updated": "2025-09-04 12:05:43", - "updated_at": 1756958743415, - "created": "2024-04-02 18:25:12", - "created_at": 1712053512213, - "link": "https://music.163.com/#/discover/toplist?id=9651277674" - }, - { - "id": 10131772880, - "name": "昊铂车友爱听榜", - "description": null, - "cover": "https://p1.music.126.net/EL7H4rkKejZY7Uv54EFNXg==/109951169655010112.jpg", - "update_frequency": "每周一更新", - "updated": "2025-09-01 16:05:03", - "updated_at": 1756713903085, - "created": "2024-06-04 16:50:00", - "created_at": 1717491000945, - "link": "https://music.163.com/#/discover/toplist?id=10131772880" - }, - { - "id": 10162841534, - "name": "埃安车友爱听榜", - "description": "埃安车友平时都在听什么??", - "cover": "https://p1.music.126.net/FcP1U6Bck0wPKqd0XgBwSQ==/109951169679731241.jpg", - "update_frequency": "每周一更新", - "updated": "2025-09-01 16:05:05", - "updated_at": 1756713905568, - "created": "2024-06-12 13: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://p1.music.126.net/0E6MzYzyA5uvQ4CSoIG2mw==/109951169739660034.jpg", - "update_frequency": "每周五更新", - "updated": "2025-08-29 12:05:45", - "updated_at": 1756440345198, - "created": "2024-06-25 18:14:05", - "created_at": 1719310445382, - "link": "https://music.163.com/#/discover/toplist?id=12225155968" - }, - { - "id": 12344472377, - "name": "黑胶VIP限免榜", - "description": "云音乐站内热度最高的限免播放歌曲TOP50,每日更新。\n人气旋律一听就会爱上!现在马上进入免费模式(点击云音乐首页左上角侧边栏,选择“免费听歌”)畅听全榜吧!", - "cover": "https://p1.music.126.net/WXCSf4ZNcDCdOTY5ixm3Bg==/109951169809318325.jpg", - "update_frequency": "每天更新", - "updated": "2025-09-04 12:05:45", - "updated_at": 1756958745487, - "created": "2024-07-23 16:08:37", - "created_at": 1721722117311, - "link": "https://music.163.com/#/discover/toplist?id=12344472377" - }, - { - "id": 12717025277, - "name": "吉利车友爱听榜", - "description": null, - "cover": "https://p1.music.126.net/XVmZb3JSyrwMgqu9WVz61A==/109951170037568570.jpg", - "update_frequency": "每周一更新", - "updated": "2025-09-01 16:05:01", - "updated_at": 1756713901625, - "created": "2024-10-12 13:44:04", - "created_at": 1728711844151, - "link": "https://music.163.com/#/discover/toplist?id=12717025277" - } - ] -} \ No newline at end of file diff --git a/frontend/60sapi/生成要求模板.txt b/frontend/60sapi/生成要求模板.txt deleted file mode 100755 index 975a3074..00000000 --- a/frontend/60sapi/生成要求模板.txt +++ /dev/null @@ -1,7 +0,0 @@ -1.生成为静态网页,js,css,html分离出来,不要混合在一起放入html里,难以阅读 -2.网页要适配手机端,电脑端和平板端三个设备分别做不同的css格式,优先优化手机端用户体验 -3.网页默认风格以淡绿色清新风格为主,除非用户要求 -4.尽量不要引用外部css,js,实在要引用就使用中国国内的cdn,否则用户可能加载不出来 -5.返回接口.json储存了网页api返回的数据格式 -6.严格按照用户要求执行,不得随意添加什么注解,如“以下数据来自...” -8.在css中有关背景的css单独一个css文件,方便我直接迁移 \ No newline at end of file diff --git a/frontend/aimodelapp/AI写诗小助手/env.js b/frontend/aimodelapp/AI写诗小助手/env.js deleted file mode 100755 index 12358bc2..00000000 --- a/frontend/aimodelapp/AI写诗小助手/env.js +++ /dev/null @@ -1,35 +0,0 @@ -// AI写诗小助手配置文件 -const CONFIG = { - // GitHub API 配置 - GITHUB_TOKEN: '', - endpoint: 'https://models.github.ai/inference/chat/completions', - MODEL_NAME: 'openai/gpt-4o-mini', - - // 专业的古诗生成提示词 - createPoemPrompt: (theme) => { - return `你是一位精通中国古典诗词的大师,请根据用户提供的主题创作一首优美的古诗。 - -要求: -1. 严格遵循中国古诗的格律和韵律 -2. 可以是五言绝句、七言绝句、五言律诗或七言律诗 -3. 注重意境的营造,体现中国传统文化的美感 -4. 用词典雅,富有诗意 -5. 根据主题选择合适的风格(豪放、婉约、田园、边塞等) -6. 确保押韵和平仄协调 -7. 请先给诗歌起一个优美的标题,然后换行写出诗歌内容 -8. 格式:标题\n诗歌正文 -9. 注意排版对齐,标题居中,诗歌正文左对齐 -10. 诗歌内容必须是中文 - -主题:${theme} - -请创作一首古诗:`; - } -}; - -// 导出配置 -if (typeof module !== 'undefined' && module.exports) { - module.exports = CONFIG; -} else { - window.CONFIG = CONFIG; -} \ No newline at end of file diff --git a/frontend/aimodelapp/AI写诗小助手/index.html b/frontend/aimodelapp/AI写诗小助手/index.html deleted file mode 100755 index cbef4f15..00000000 --- a/frontend/aimodelapp/AI写诗小助手/index.html +++ /dev/null @@ -1,317 +0,0 @@ - - - - - - AI古诗生成器 - - - -
    -
    -

    AI古诗生成器

    -

    让人工智能为您创作优美的中国古诗

    -
    - - - -
    - - -
    - - - -
    -

    生成的古诗

    -
    正在创作中,请稍候...
    -
    点击"生成古诗"按钮,AI将为您创作优美的古诗
    -
    -
    - - - - - \ No newline at end of file diff --git a/frontend/aimodelapp/AI变量命名助手/env.js b/frontend/aimodelapp/AI变量命名助手/env.js deleted file mode 100755 index 4b00731e..00000000 --- a/frontend/aimodelapp/AI变量命名助手/env.js +++ /dev/null @@ -1,68 +0,0 @@ -// AI变量命名助手配置文件 -const CONFIG = { - // GitHub Models API 配置 - GITHUB_TOKEN: '', - API_URL: 'https://models.github.ai/inference/chat/completions', - MODEL_NAME: 'openai/gpt-4o-mini', - - // AI提示词模板 - createNamingPrompt: (description) => { - return `你是一个专业的变量命名助手。请根据以下描述为变量生成合适的名称: - -描述:${description} - -请为每种命名规范生成3个变量名建议: -1. camelCase (驼峰命名法) -2. PascalCase (帕斯卡命名法) -3. snake_case (下划线命名法) -4. kebab-case (短横线命名法) -5. CONSTANT_CASE (常量命名法) - -要求: -- 变量名要准确反映功能和用途 -- 严格遵循各自的命名规范 -- 避免使用缩写,除非是广泛认知的缩写 -- 名称要简洁但具有描述性 -- 考虑代码的可读性和维护性 - -请按以下JSON格式返回: -{ - "suggestions": { - "camelCase": [ - {"name": "变量名1", "description": "解释说明1"}, - {"name": "变量名2", "description": "解释说明2"}, - {"name": "变量名3", "description": "解释说明3"} - ], - "PascalCase": [ - {"name": "变量名1", "description": "解释说明1"}, - {"name": "变量名2", "description": "解释说明2"}, - {"name": "变量名3", "description": "解释说明3"} - ], - "snake_case": [ - {"name": "变量名1", "description": "解释说明1"}, - {"name": "变量名2", "description": "解释说明2"}, - {"name": "变量名3", "description": "解释说明3"} - ], - "kebab-case": [ - {"name": "变量名1", "description": "解释说明1"}, - {"name": "变量名2", "description": "解释说明2"}, - {"name": "变量名3", "description": "解释说明3"} - ], - "CONSTANT_CASE": [ - {"name": "变量名1", "description": "解释说明1"}, - {"name": "变量名2", "description": "解释说明2"}, - {"name": "变量名3", "description": "解释说明3"} - ] - } -} - -只返回JSON格式的结果,不要包含其他文字。`; - } -}; - -// 导出配置 -if (typeof module !== 'undefined' && module.exports) { - module.exports = CONFIG; -} else { - window.CONFIG = CONFIG; -} \ No newline at end of file diff --git a/frontend/aimodelapp/AI变量命名助手/index.html b/frontend/aimodelapp/AI变量命名助手/index.html deleted file mode 100755 index 6e76ba22..00000000 --- a/frontend/aimodelapp/AI变量命名助手/index.html +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - AI变量命名助手 - - - -
    -
    -

    AI变量命名助手

    -

    让AI帮您生成规范的变量名

    -
    - -
    -
    - - -
    - - - - -
    - -
    -

    推荐的变量名

    -
    正在生成中,请稍候...
    -
    -
    点击"生成变量名"按钮,AI将为您推荐合适的变量名
    -
    -
    -
    - - - - - \ No newline at end of file diff --git a/frontend/aimodelapp/AI变量命名助手/script.js b/frontend/aimodelapp/AI变量命名助手/script.js deleted file mode 100755 index 0fc146b2..00000000 --- a/frontend/aimodelapp/AI变量命名助手/script.js +++ /dev/null @@ -1,251 +0,0 @@ -// 从配置文件导入设置 -// 配置在 env.js 文件中定义 - -// DOM 元素 -const descriptionInput = document.getElementById('description'); -const generateBtn = document.getElementById('generateBtn'); -const loadingDiv = document.getElementById('loading'); -const suggestionsContainer = document.getElementById('suggestions'); - -// 命名规范转换函数 -const namingConventions = { - camelCase: (words) => { - if (words.length === 0) return ''; - return words[0].toLowerCase() + words.slice(1).map(word => - word.charAt(0).toUpperCase() + word.slice(1).toLowerCase() - ).join(''); - }, - - PascalCase: (words) => { - return words.map(word => - word.charAt(0).toUpperCase() + word.slice(1).toLowerCase() - ).join(''); - }, - - snake_case: (words) => { - return words.map(word => word.toLowerCase()).join('_'); - }, - - 'kebab-case': (words) => { - return words.map(word => word.toLowerCase()).join('-'); - }, - - CONSTANT_CASE: (words) => { - return words.map(word => word.toUpperCase()).join('_'); - } -}; - - - -// 调用GitHub Models API -async function callGitHubModelsAPI(prompt) { - try { - const response = await fetch(CONFIG.API_URL, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'Authorization': `Bearer ${CONFIG.GITHUB_TOKEN}` - }, - body: JSON.stringify({ - messages: [ - { - role: 'user', - content: prompt - } - ], - model: CONFIG.MODEL_NAME, - temperature: 0.7, - max_tokens: 1000 - }) - }); - - if (!response.ok) { - throw new Error(`API请求失败: ${response.status} ${response.statusText}`); - } - - const data = await response.json(); - return data.choices[0].message.content; - } catch (error) { - console.error('API调用错误:', error); - throw error; - } -} - -// 解析AI响应 -function parseAIResponse(response) { - try { - // 尝试直接解析JSON - const parsed = JSON.parse(response); - return parsed.suggestions || {}; - } catch (error) { - // 如果直接解析失败,尝试提取JSON部分 - const jsonMatch = response.match(/\{[\s\S]*\}/); - if (jsonMatch) { - try { - const parsed = JSON.parse(jsonMatch[0]); - return parsed.suggestions || {}; - } catch (e) { - console.error('JSON解析失败:', e); - } - } - - // 如果JSON解析失败,返回空对象 - console.error('无法解析AI响应:', response); - return {}; - } -} - - - -// 显示建议 -function displaySuggestions(suggestions) { - suggestionsContainer.innerHTML = ''; - - if (!suggestions || Object.keys(suggestions).length === 0) { - suggestionsContainer.innerHTML = '
    暂无建议,请尝试重新生成
    '; - return; - } - - // 命名规范的显示名称 - const conventionNames = { - 'camelCase': 'camelCase (驼峰命名法)', - 'PascalCase': 'PascalCase (帕斯卡命名法)', - 'snake_case': 'snake_case (下划线命名法)', - 'kebab-case': 'kebab-case (短横线命名法)', - 'CONSTANT_CASE': 'CONSTANT_CASE (常量命名法)' - }; - - // 按命名规范分组显示 - Object.keys(suggestions).forEach(convention => { - if (suggestions[convention] && suggestions[convention].length > 0) { - // 创建分组标题 - const groupTitle = document.createElement('div'); - groupTitle.className = 'convention-group-title'; - groupTitle.textContent = conventionNames[convention] || convention; - suggestionsContainer.appendChild(groupTitle); - - // 显示该规范下的建议 - suggestions[convention].forEach(suggestion => { - const suggestionElement = document.createElement('div'); - suggestionElement.className = 'suggestion-item'; - suggestionElement.innerHTML = ` -
    ${suggestion.name}
    -
    ${suggestion.description}
    - - `; - suggestionsContainer.appendChild(suggestionElement); - }); - } - }); -} - -// 复制到剪贴板 -function copyToClipboard(text, button) { - navigator.clipboard.writeText(text).then(() => { - showSuccessToast('已复制到剪贴板'); - button.textContent = '已复制'; - setTimeout(() => { - button.textContent = '复制'; - }, 2000); - }).catch(err => { - console.error('复制失败:', err); - // 备用复制方法 - const textArea = document.createElement('textarea'); - textArea.value = text; - document.body.appendChild(textArea); - textArea.select(); - try { - document.execCommand('copy'); - showSuccessToast('已复制到剪贴板'); - button.textContent = '已复制'; - setTimeout(() => { - button.textContent = '复制'; - }, 2000); - } catch (e) { - showErrorMessage('复制失败,请手动复制'); - } - document.body.removeChild(textArea); - }); -} - -// 显示成功提示 -function showSuccessToast(message) { - const toast = document.createElement('div'); - toast.className = 'success-toast'; - toast.textContent = message; - document.body.appendChild(toast); - - setTimeout(() => { - toast.classList.add('show'); - }, 100); - - setTimeout(() => { - toast.classList.remove('show'); - setTimeout(() => { - document.body.removeChild(toast); - }, 300); - }, 2000); -} - -// 显示错误信息 -function showErrorMessage(message) { - const errorDiv = document.createElement('div'); - errorDiv.className = 'error'; - errorDiv.textContent = message; - suggestionsContainer.innerHTML = ''; - suggestionsContainer.appendChild(errorDiv); -} - -// 显示加载状态 -function showLoading(show) { - loadingDiv.style.display = show ? 'block' : 'none'; - generateBtn.disabled = show; - generateBtn.textContent = show ? '生成中...' : '生成变量名'; -} - -// 生成变量名建议 -async function generateSuggestions() { - const description = descriptionInput.value.trim(); - - if (!description) { - showErrorMessage('请输入变量描述'); - return; - } - - showLoading(true); - suggestionsContainer.innerHTML = ''; - - try { - const prompt = CONFIG.createNamingPrompt(description); - const response = await callGitHubModelsAPI(prompt); - const suggestions = parseAIResponse(response); - - displaySuggestions(suggestions); - } catch (error) { - console.error('生成建议失败:', error); - showErrorMessage(`生成失败: ${error.message}`); - } finally { - showLoading(false); - } -} - -// 事件监听器 -generateBtn.addEventListener('click', generateSuggestions); - -// 回车键生成 -descriptionInput.addEventListener('keypress', (e) => { - if (e.key === 'Enter' && !e.shiftKey) { - e.preventDefault(); - generateSuggestions(); - } -}); - -// 页面加载完成后的初始化 -document.addEventListener('DOMContentLoaded', () => { - // 设置默认占位符 - suggestionsContainer.innerHTML = '
    请输入变量描述,然后点击生成按钮获取所有命名规范的建议
    '; -}); - -// 导出函数供HTML调用 -window.copyToClipboard = copyToClipboard; -window.generateSuggestions = generateSuggestions; \ No newline at end of file diff --git a/frontend/aimodelapp/AI变量命名助手/styles.css b/frontend/aimodelapp/AI变量命名助手/styles.css deleted file mode 100755 index 3174cc43..00000000 --- a/frontend/aimodelapp/AI变量命名助手/styles.css +++ /dev/null @@ -1,365 +0,0 @@ -/* 全局样式重置 */ -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -/* 主体样式 */ -body { - font-family: 'Microsoft YaHei', '微软雅黑', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - min-height: 100vh; - padding: 20px; - color: #333; - line-height: 1.6; -} - -/* 容器样式 */ -.container { - max-width: 700px; - margin: 0 auto; - background: rgba(255, 255, 255, 0.95); - border-radius: 20px; - padding: 30px; - box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1); - backdrop-filter: blur(10px); -} - -/* 头部样式 */ -.header { - text-align: center; - margin-bottom: 30px; -} - -.title { - font-size: 2.5rem; - color: #4a5568; - margin-bottom: 10px; - font-weight: 300; - letter-spacing: 2px; -} - -.subtitle { - color: #718096; - font-size: 1rem; - margin-bottom: 20px; -} - -/* 表单样式 */ -.form-section { - margin-bottom: 30px; -} - -.form-group { - margin-bottom: 25px; -} - -.form-label { - display: block; - margin-bottom: 8px; - font-weight: 500; - color: #4a5568; - font-size: 1rem; -} - -.form-input { - width: 100%; - padding: 15px; - border: 2px solid #e2e8f0; - border-radius: 12px; - font-size: 1rem; - transition: all 0.3s ease; - background: #f7fafc; - font-family: inherit; -} - -.form-input:focus { - outline: none; - border-color: #667eea; - background: #fff; - box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1); -} - -.textarea { - resize: vertical; - min-height: 120px; -} - -.select { - cursor: pointer; - appearance: none; - background-image: url('data:image/svg+xml;charset=US-ASCII,'); - background-repeat: no-repeat; - background-position: right 15px center; - background-size: 12px; - padding-right: 40px; -} - -/* 按钮样式 */ -.btn { - width: 100%; - padding: 15px; - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - color: white; - border: none; - border-radius: 12px; - font-size: 1.1rem; - font-weight: 500; - cursor: pointer; - transition: all 0.3s ease; - margin-bottom: 25px; -} - -.btn:hover { - transform: translateY(-2px); - box-shadow: 0 10px 25px rgba(102, 126, 234, 0.3); -} - -.btn:active { - transform: translateY(0); -} - -.btn:disabled { - opacity: 0.6; - cursor: not-allowed; - transform: none; -} - -/* 结果区域样式 */ -.result-section { - margin-top: 30px; -} - -.result-title { - font-size: 1.3rem; - color: #4a5568; - margin-bottom: 15px; - text-align: center; - font-weight: 500; -} - -.loading { - display: none; - text-align: center; - color: #667eea; - font-style: italic; - padding: 20px; -} - -.suggestions-container { - background: #f7fafc; - border: 2px solid #e2e8f0; - border-radius: 12px; - padding: 20px; - min-height: 150px; -} - -.placeholder { - text-align: center; - color: #a0aec0; - font-style: italic; - padding: 40px 20px; -} - -/* 分组标题样式 */ -.convention-group-title { - font-size: 1.1rem; - font-weight: 600; - color: #4a5568; - margin: 20px 0 10px 0; - padding: 8px 12px; - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - color: white; - border-radius: 8px; - text-align: center; -} - -.convention-group-title:first-child { - margin-top: 0; -} - -/* 建议项样式 */ -.suggestion-item { - background: #fff; - border: 1px solid #e2e8f0; - border-radius: 8px; - padding: 15px; - margin-bottom: 10px; - transition: all 0.2s ease; - cursor: pointer; - position: relative; -} - -.suggestion-item:hover { - border-color: #667eea; - box-shadow: 0 2px 8px rgba(102, 126, 234, 0.1); -} - -.suggestion-item:last-child { - margin-bottom: 0; -} - -.variable-name { - font-family: 'Consolas', 'Monaco', 'Courier New', monospace; - font-size: 1.1rem; - font-weight: 600; - color: #2d3748; - margin-bottom: 5px; -} - -.variable-description { - font-size: 0.9rem; - color: #718096; - line-height: 1.4; -} - -.copy-btn { - position: absolute; - top: 10px; - right: 10px; - background: #667eea; - color: white; - border: none; - border-radius: 6px; - padding: 5px 10px; - font-size: 0.8rem; - cursor: pointer; - opacity: 0; - transition: opacity 0.2s ease; -} - -.suggestion-item:hover .copy-btn { - opacity: 1; -} - -.copy-btn:hover { - background: #5a67d8; -} - -/* 错误样式 */ -.error { - color: #e53e3e; - background: #fed7d7; - border: 1px solid #feb2b2; - padding: 15px; - border-radius: 8px; - margin-top: 15px; -} - -/* 成功提示 */ -.success-toast { - position: fixed; - top: 20px; - right: 20px; - background: #48bb78; - color: white; - padding: 12px 20px; - border-radius: 8px; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); - z-index: 1000; - opacity: 0; - transform: translateX(100%); - transition: all 0.3s ease; -} - -.success-toast.show { - opacity: 1; - transform: translateX(0); -} - -/* 响应式设计 */ -@media (max-width: 768px) { - body { - padding: 10px; - } - - .container { - padding: 20px; - margin: 10px; - } - - .title { - font-size: 2rem; - } - - .form-input { - padding: 12px; - } - - .btn { - padding: 12px; - } - - .suggestions-container { - padding: 15px; - } - - .suggestion-item { - padding: 12px; - } - - .copy-btn { - position: static; - opacity: 1; - margin-top: 8px; - width: 100%; - } -} - -@media (max-width: 480px) { - .title { - font-size: 1.8rem; - letter-spacing: 1px; - } - - .container { - padding: 15px; - } - - .form-input { - padding: 10px; - } - - .suggestion-item { - padding: 10px; - } - - .variable-name { - font-size: 1rem; - } - - .variable-description { - font-size: 0.85rem; - } -} - -/* 动画效果 */ -@keyframes fadeIn { - from { - opacity: 0; - transform: translateY(10px); - } - to { - opacity: 1; - transform: translateY(0); - } -} - -.suggestion-item { - animation: fadeIn 0.3s ease; -} - -/* 加载动画 */ -@keyframes pulse { - 0%, 100% { - opacity: 1; - } - 50% { - opacity: 0.5; - } -} - -.loading { - animation: pulse 1.5s ease-in-out infinite; -} \ No newline at end of file diff --git a/frontend/aimodelapp/AI姓名评测/env.js b/frontend/aimodelapp/AI姓名评测/env.js deleted file mode 100755 index 8b6efdf1..00000000 --- a/frontend/aimodelapp/AI姓名评测/env.js +++ /dev/null @@ -1,47 +0,0 @@ -// AI姓名评测配置文件 -const CONFIG = { - // GitHub API 配置 - GITHUB_TOKEN: '', - endpoint: 'https://models.github.ai/inference/chat/completions', - model: 'deepseek/DeepSeek-V3-0324', - - // 专业的姓名分析提示词 - createNameAnalysisPrompt: (name) => { - return `你是一位专业的姓名学专家和语言学家,请对输入的姓名进行全面分析。请直接输出分析结果,不要包含任何思考过程或标签。 - -姓名:${name} - -请按照以下格式严格输出分析结果: - -【稀有度评分】 -评分:X% -评价:[对稀有度的详细说明,包括姓氏和名字的常见程度分析] - -【音韵评价】 -评分:X% -评价:[对音韵美感的分析,包括声调搭配、读音流畅度、音律和谐度等] - -【含义解读】 -[详细分析姓名的寓意内涵,包括: -1. 姓氏的历史渊源和文化背景 -2. 名字各字的含义和象征 -3. 整体姓名的寓意组合 -4. 可能体现的父母期望或文化内涵 -5. 与传统文化、诗词典故的关联等] - -要求: -1. 评分必须是1-100的整数百分比,要有明显区分度,避免雷同 -2. 分析要专业、客观、有依据,评分要根据实际情况有所差异 -3. 含义解读要详细深入,至少150字 -4. 严格按照上述格式输出,不要添加思考过程、标签或其他内容 -5. 如果是生僻字或罕见姓名,要特别说明 -6. 直接输出最终结果,不要显示推理过程`; - } -}; - -// 导出配置 -if (typeof module !== 'undefined' && module.exports) { - module.exports = CONFIG; -} else { - window.CONFIG = CONFIG; -} \ No newline at end of file diff --git a/frontend/aimodelapp/AI姓名评测/index.html b/frontend/aimodelapp/AI姓名评测/index.html deleted file mode 100755 index 42618b7e..00000000 --- a/frontend/aimodelapp/AI姓名评测/index.html +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - AI姓名评测 - - - -
    -
    -

    AI姓名评测

    -

    智能分析姓名的稀有度、音韵美感与寓意内涵

    -
    - -
    - - -
    - - - -
    -

    分析结果

    -
    正在分析中,请稍候...
    - -
    -
    -

    稀有度评分

    -
    --%
    -
    点击"开始分析"查看结果
    -
    - -
    -

    音韵评价

    -
    --%
    -
    点击"开始分析"查看结果
    -
    - -
    -

    含义解读

    -
    点击"开始分析"查看姓名的深层寓意
    -
    -
    -
    -
    - - - - - \ No newline at end of file diff --git a/frontend/aimodelapp/AI姓名评测/script.js b/frontend/aimodelapp/AI姓名评测/script.js deleted file mode 100755 index 4c21830a..00000000 --- a/frontend/aimodelapp/AI姓名评测/script.js +++ /dev/null @@ -1,258 +0,0 @@ -// 从配置文件导入设置 -// 配置在 env.js 文件中定义 - -// DOM 元素 -const nameInput = document.getElementById('nameInput'); -const analyzeBtn = document.getElementById('analyzeBtn'); -const loading = document.getElementById('loading'); -const rarityScore = document.getElementById('rarityScore'); -const rarityDesc = document.getElementById('rarityDesc'); -const phoneticScore = document.getElementById('phoneticScore'); -const phoneticDesc = document.getElementById('phoneticDesc'); -const meaningAnalysis = document.getElementById('meaningAnalysis'); - - - -// 解析AI返回的分析结果 -function parseAnalysisResult(content) { - const result = { - rarityScore: '--%', - rarityDesc: '解析失败', - phoneticScore: '--%', - phoneticDesc: '解析失败', - meaningAnalysis: '解析失败' - }; - - try { - // 过滤掉DeepSeek的思考标签内容 - let cleanContent = content.replace(/[\s\S]*?<\/think>/gi, ''); - cleanContent = cleanContent.replace(/[\s\S]*$/gi, ''); // 处理未闭合的think标签 - cleanContent = cleanContent.trim(); - - console.log('清理后的内容:', cleanContent); - - // 提取稀有度评分(百分比格式) - const rarityMatch = cleanContent.match(/【稀有度评分】[\s\S]*?评分:(\d+)%[\s\S]*?评价:([\s\S]*?)(?=【|$)/); - if (rarityMatch) { - result.rarityScore = rarityMatch[1] + '%'; - result.rarityDesc = rarityMatch[2].trim(); - } - - // 提取音韵评价(百分比格式) - const phoneticMatch = cleanContent.match(/【音韵评价】[\s\S]*?评分:(\d+)%[\s\S]*?评价:([\s\S]*?)(?=【|$)/); - if (phoneticMatch) { - result.phoneticScore = phoneticMatch[1] + '%'; - result.phoneticDesc = phoneticMatch[2].trim(); - } - - // 提取含义解读 - const meaningMatch = cleanContent.match(/【含义解读】[\s\S]*?\n([\s\S]+)$/); - if (meaningMatch) { - result.meaningAnalysis = meaningMatch[1].trim(); - } - } catch (error) { - console.error('解析结果时出错:', error); - } - - return result; -} - -// 简单的markdown解析函数 -function parseMarkdown(text) { - if (!text || typeof text !== 'string') return text; - - // 处理加粗 **text** 或 __text__ - let parsed = text.replace(/\*\*(.*?)\*\*/g, '$1'); - parsed = parsed.replace(/__(.*?)__/g, '$1'); - - // 处理斜体 *text* 或 _text_ - parsed = parsed.replace(/\*(.*?)\*/g, '$1'); - parsed = parsed.replace(/_(.*?)_/g, '$1'); - - // 处理无序列表 - const lines = parsed.split('\n'); - let inList = false; - let result = []; - - for (let i = 0; i < lines.length; i++) { - const line = lines[i].trim(); - - // 检查是否是列表项(以 - 开头,后面跟空格) - if (line.match(/^-\s+/)) { - if (!inList) { - result.push('
      '); - inList = true; - } - // 移除开头的 "- " 并包装为
    • - const listContent = line.replace(/^-\s+/, ''); - result.push(`
    • ${listContent}
    • `); - } else { - if (inList) { - result.push('
    '); - inList = false; - } - if (line) { - result.push(line); - } - } - } - - // 如果最后还在列表中,需要关闭列表 - if (inList) { - result.push(''); - } - - // 重新组合,用
    连接非列表行 - parsed = result.join('
    '); - - // 清理多余的
    标签(在列表前后) - parsed = parsed.replace(/
      /g, '
        '); - parsed = parsed.replace(/<\/ul>
        /g, '
      '); - parsed = parsed.replace(/
    • /g, '
    • '); - parsed = parsed.replace(/<\/li>
      /g, '
    • '); - - return parsed; -} - -// 更新显示结果 -function updateResults(result) { - rarityScore.textContent = result.rarityScore; - rarityDesc.innerHTML = parseMarkdown(result.rarityDesc); - phoneticScore.textContent = result.phoneticScore; - phoneticDesc.innerHTML = parseMarkdown(result.phoneticDesc); - meaningAnalysis.innerHTML = parseMarkdown(result.meaningAnalysis); -} - -// 重置结果显示 -function resetResults() { - rarityScore.textContent = '--%'; - rarityDesc.innerHTML = '点击"开始分析"查看结果'; - phoneticScore.textContent = '--%'; - phoneticDesc.innerHTML = '点击"开始分析"查看结果'; - meaningAnalysis.innerHTML = '点击"开始分析"查看姓名的深层寓意'; -} - -// 显示错误信息 -function showError(message) { - // 清除之前的错误信息 - const existingError = document.querySelector('.error'); - if (existingError) { - existingError.remove(); - } - - // 创建新的错误信息 - const errorDiv = document.createElement('div'); - errorDiv.className = 'error'; - errorDiv.textContent = `分析失败:${message}。`; - document.querySelector('.result-section').appendChild(errorDiv); -} - -// 姓名验证 -function validateName(name) { - if (!name) { - return '请输入姓名'; - } - if (name.length < 2) { - return '姓名至少需要2个字符'; - } - if (name.length > 10) { - return '姓名不能超过10个字符'; - } - if (!/^[\u4e00-\u9fa5a-zA-Z]+$/.test(name)) { - return '姓名只能包含中文或英文字符'; - } - return null; -} - -// 主要分析函数 -async function analyzeName() { - const name = nameInput.value.trim(); - - // 验证输入 - const validationError = validateName(name); - if (validationError) { - alert(validationError); - return; - } - - // 显示加载状态 - analyzeBtn.disabled = true; - analyzeBtn.textContent = '分析中...'; - loading.style.display = 'block'; - resetResults(); - - // 清除之前的错误信息 - const existingError = document.querySelector('.error'); - if (existingError) { - existingError.remove(); - } - - const requestBody = { - model: CONFIG.model, - messages: [{ - role: "user", - content: CONFIG.createNameAnalysisPrompt(name) - }], - temperature: 0.7, - max_tokens: 1000 - }; - - try { - const response = await fetch(CONFIG.endpoint, { - method: 'POST', - headers: { - 'Accept': 'application/vnd.github+json', - 'Authorization': `Bearer ${CONFIG.GITHUB_TOKEN}`, - 'X-GitHub-Api-Version': '2022-11-28', - 'Content-Type': 'application/json' - }, - body: JSON.stringify(requestBody) - }); - - // 检查HTTP状态码 - if (response.status === 429) { - throw new Error('短时间内请求次数过多,请休息一下!'); - } - - if (!response.ok) { - throw new Error(`请求失败: ${response.status} ${response.statusText}`); - } - - const data = await response.json(); - - if (data?.choices?.[0]?.message?.content) { - const analysisResult = parseAnalysisResult(data.choices[0].message.content.trim()); - updateResults(analysisResult); - } else { - throw new Error('AI响应格式异常'); - } - } catch (error) { - console.error('分析姓名时出错:', error); - showError(error.message); - resetResults(); - } finally { - // 恢复按钮状态 - analyzeBtn.disabled = false; - analyzeBtn.textContent = '开始分析'; - loading.style.display = 'none'; - } -} - -// 事件监听器 -analyzeBtn.addEventListener('click', analyzeName); - -// 回车键快捷分析 -nameInput.addEventListener('keypress', (e) => { - if (e.key === 'Enter') { - e.preventDefault(); - analyzeName(); - } -}); - -// 输入框内容变化时清除错误信息 -nameInput.addEventListener('input', () => { - const existingError = document.querySelector('.error'); - if (existingError) { - existingError.remove(); - } -}); \ No newline at end of file diff --git a/frontend/aimodelapp/AI姓名评测/styles.css b/frontend/aimodelapp/AI姓名评测/styles.css deleted file mode 100755 index dc1325ec..00000000 --- a/frontend/aimodelapp/AI姓名评测/styles.css +++ /dev/null @@ -1,249 +0,0 @@ -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -body { - font-family: 'Microsoft YaHei', '微软雅黑', Arial, sans-serif; - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - min-height: 100vh; - padding: 20px; - color: #333; -} - -.container { - max-width: 700px; - margin: 0 auto; - background: rgba(255, 255, 255, 0.95); - border-radius: 20px; - padding: 30px; - box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1); - backdrop-filter: blur(10px); -} - -.header { - text-align: center; - margin-bottom: 30px; -} - -.title { - font-size: 2.5rem; - color: #4a5568; - margin-bottom: 10px; - font-weight: 300; - letter-spacing: 2px; -} - -.subtitle { - color: #718096; - font-size: 1rem; - margin-bottom: 20px; -} - -.form-group { - margin-bottom: 25px; -} - -.form-label { - display: block; - margin-bottom: 8px; - font-weight: 500; - color: #4a5568; - font-size: 1rem; -} - -.form-input { - width: 100%; - padding: 15px; - border: 2px solid #e2e8f0; - border-radius: 12px; - font-size: 1rem; - transition: all 0.3s ease; - background: #f7fafc; - text-align: center; -} - -.form-input:focus { - outline: none; - border-color: #667eea; - background: #fff; - box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1); -} - -.btn { - width: 100%; - padding: 15px; - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - color: white; - border: none; - border-radius: 12px; - font-size: 1.1rem; - font-weight: 500; - cursor: pointer; - transition: all 0.3s ease; - margin-bottom: 25px; -} - -.btn:hover { - transform: translateY(-2px); - box-shadow: 0 10px 25px rgba(102, 126, 234, 0.3); -} - -.btn:active { - transform: translateY(0); -} - -.btn:disabled { - opacity: 0.6; - cursor: not-allowed; - transform: none; -} - -.result-section { - margin-top: 30px; -} - -.result-title { - font-size: 1.3rem; - color: #4a5568; - margin-bottom: 20px; - text-align: center; - font-weight: 500; -} - -.loading { - display: none; - text-align: center; - color: #667eea; - font-style: italic; - margin-bottom: 20px; -} - -.result-container { - display: grid; - gap: 20px; - grid-template-columns: 1fr; -} - -.result-card { - background: #f7fafc; - border: 2px solid #e2e8f0; - border-radius: 12px; - padding: 20px; - transition: all 0.3s ease; -} - -.result-card:hover { - border-color: #667eea; - box-shadow: 0 5px 15px rgba(102, 126, 234, 0.1); -} - -.card-title { - font-size: 1.1rem; - color: #4a5568; - margin-bottom: 15px; - text-align: center; - font-weight: 600; -} - -.score-display { - font-size: 2.5rem; - font-weight: bold; - text-align: center; - margin-bottom: 10px; - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; -} - -.score-desc { - text-align: center; - color: #718096; - font-size: 0.9rem; - line-height: 1.5; -} - -.meaning-content { - color: #2d3748; - line-height: 1.8; - font-size: 1rem; - text-align: left; - white-space: pre-wrap; -} - -.error { - color: #e53e3e; - background: #fed7d7; - border: 1px solid #feb2b2; - padding: 15px; - border-radius: 8px; - margin-top: 15px; -} - -/* 平板和桌面端优化 */ -@media (min-width: 768px) { - .result-container { - grid-template-columns: 1fr 1fr; - } - - .result-card:last-child { - grid-column: 1 / -1; - } -} - -/* 手机端优化 */ -@media (max-width: 768px) { - body { - padding: 10px; - } - - .container { - padding: 20px; - margin: 10px; - } - - .title { - font-size: 2rem; - } - - .form-input { - padding: 12px; - } - - .btn { - padding: 12px; - } - - .result-card { - padding: 15px; - } - - .score-display { - font-size: 2rem; - } -} - -@media (max-width: 480px) { - .title { - font-size: 1.8rem; - letter-spacing: 1px; - } - - .container { - padding: 15px; - } - - .result-card { - padding: 12px; - } - - .score-display { - font-size: 1.8rem; - } - - .meaning-content { - font-size: 0.9rem; - } -} \ No newline at end of file diff --git a/frontend/aimodelapp/生成要求.txt b/frontend/aimodelapp/生成要求.txt deleted file mode 100755 index d921a0c2..00000000 --- a/frontend/aimodelapp/生成要求.txt +++ /dev/null @@ -1,12 +0,0 @@ -1.写一个静态网页来调用github model 来完成应用功能 -2.网页清新风格,颜色随意,app风格,适配手机端和电脑端,优先优化手机端用户体验 -3.默认github的调用密钥是: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 -4.默认调用AI模型为 "openai/gpt-4o-mini" -5.把js,css,html分开储存,每个功能分每个模块,避免单个文件过大问题 -6.默认github ai调用模型地址是:'https://models.github.ai/inference/chat/completions' -比如这样: -// GitHub API 配置 -const GITHUB_TOKEN = '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'; -const endpoint = 'https://models.github.ai/inference/chat/completions'; -const model = 'deepseek/DeepSeek-V3-0324'; - diff --git a/frontend/src/env.backup b/frontend/env.backup old mode 100755 new mode 100644 similarity index 100% rename from frontend/src/env.backup rename to frontend/env.backup diff --git a/frontend/node_modules/.bin/acorn b/frontend/node_modules/.bin/acorn index cf767603..679bd163 120000 --- a/frontend/node_modules/.bin/acorn +++ b/frontend/node_modules/.bin/acorn @@ -1 +1,16 @@ -../acorn/bin/acorn \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../acorn/bin/acorn" "$@" +else + exec node "$basedir/../acorn/bin/acorn" "$@" +fi diff --git a/frontend/node_modules/.bin/ansi-html b/frontend/node_modules/.bin/ansi-html index 7e3f8fb8..f4749930 120000 --- a/frontend/node_modules/.bin/ansi-html +++ b/frontend/node_modules/.bin/ansi-html @@ -1 +1,16 @@ -../ansi-html/bin/ansi-html \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../ansi-html/bin/ansi-html" "$@" +else + exec node "$basedir/../ansi-html/bin/ansi-html" "$@" +fi diff --git a/frontend/node_modules/.bin/autoprefixer b/frontend/node_modules/.bin/autoprefixer index e876d81c..2d2ee701 120000 --- a/frontend/node_modules/.bin/autoprefixer +++ b/frontend/node_modules/.bin/autoprefixer @@ -1 +1,16 @@ -../autoprefixer/bin/autoprefixer \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../autoprefixer/bin/autoprefixer" "$@" +else + exec node "$basedir/../autoprefixer/bin/autoprefixer" "$@" +fi diff --git a/frontend/node_modules/.bin/browserslist b/frontend/node_modules/.bin/browserslist index 3cd991b2..60e71ad8 120000 --- a/frontend/node_modules/.bin/browserslist +++ b/frontend/node_modules/.bin/browserslist @@ -1 +1,16 @@ -../browserslist/cli.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../browserslist/cli.js" "$@" +else + exec node "$basedir/../browserslist/cli.js" "$@" +fi diff --git a/frontend/node_modules/.bin/css-blank-pseudo b/frontend/node_modules/.bin/css-blank-pseudo index 7cfe2ff8..b9012a9a 120000 --- a/frontend/node_modules/.bin/css-blank-pseudo +++ b/frontend/node_modules/.bin/css-blank-pseudo @@ -1 +1,16 @@ -../css-blank-pseudo/dist/cli.cjs \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../css-blank-pseudo/dist/cli.cjs" "$@" +else + exec node "$basedir/../css-blank-pseudo/dist/cli.cjs" "$@" +fi diff --git a/frontend/node_modules/.bin/css-has-pseudo b/frontend/node_modules/.bin/css-has-pseudo index 42a729c2..30358df4 120000 --- a/frontend/node_modules/.bin/css-has-pseudo +++ b/frontend/node_modules/.bin/css-has-pseudo @@ -1 +1,16 @@ -../css-has-pseudo/dist/cli.cjs \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../css-has-pseudo/dist/cli.cjs" "$@" +else + exec node "$basedir/../css-has-pseudo/dist/cli.cjs" "$@" +fi diff --git a/frontend/node_modules/.bin/css-prefers-color-scheme b/frontend/node_modules/.bin/css-prefers-color-scheme index 1e88b38a..4bae631e 120000 --- a/frontend/node_modules/.bin/css-prefers-color-scheme +++ b/frontend/node_modules/.bin/css-prefers-color-scheme @@ -1 +1,16 @@ -../css-prefers-color-scheme/dist/cli.cjs \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../css-prefers-color-scheme/dist/cli.cjs" "$@" +else + exec node "$basedir/../css-prefers-color-scheme/dist/cli.cjs" "$@" +fi diff --git a/frontend/node_modules/.bin/cssesc b/frontend/node_modules/.bin/cssesc index 487b6890..5dd9699c 120000 --- a/frontend/node_modules/.bin/cssesc +++ b/frontend/node_modules/.bin/cssesc @@ -1 +1,16 @@ -../cssesc/bin/cssesc \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../cssesc/bin/cssesc" "$@" +else + exec node "$basedir/../cssesc/bin/cssesc" "$@" +fi diff --git a/frontend/node_modules/.bin/detect b/frontend/node_modules/.bin/detect index 617e569c..96305b51 120000 --- a/frontend/node_modules/.bin/detect +++ b/frontend/node_modules/.bin/detect @@ -1 +1,16 @@ -../detect-port-alt/bin/detect-port \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../detect-port-alt/bin/detect-port" "$@" +else + exec node "$basedir/../detect-port-alt/bin/detect-port" "$@" +fi diff --git a/frontend/node_modules/.bin/detect-port b/frontend/node_modules/.bin/detect-port index 617e569c..96305b51 120000 --- a/frontend/node_modules/.bin/detect-port +++ b/frontend/node_modules/.bin/detect-port @@ -1 +1,16 @@ -../detect-port-alt/bin/detect-port \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../detect-port-alt/bin/detect-port" "$@" +else + exec node "$basedir/../detect-port-alt/bin/detect-port" "$@" +fi diff --git a/frontend/node_modules/.bin/ejs b/frontend/node_modules/.bin/ejs index 88e80d01..ec3bd4cf 120000 --- a/frontend/node_modules/.bin/ejs +++ b/frontend/node_modules/.bin/ejs @@ -1 +1,16 @@ -../ejs/bin/cli.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../ejs/bin/cli.js" "$@" +else + exec node "$basedir/../ejs/bin/cli.js" "$@" +fi diff --git a/frontend/node_modules/.bin/escodegen b/frontend/node_modules/.bin/escodegen index 01a7c325..1dbc1f02 120000 --- a/frontend/node_modules/.bin/escodegen +++ b/frontend/node_modules/.bin/escodegen @@ -1 +1,16 @@ -../escodegen/bin/escodegen.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../escodegen/bin/escodegen.js" "$@" +else + exec node "$basedir/../escodegen/bin/escodegen.js" "$@" +fi diff --git a/frontend/node_modules/.bin/esgenerate b/frontend/node_modules/.bin/esgenerate index 7d0293e6..8633c745 120000 --- a/frontend/node_modules/.bin/esgenerate +++ b/frontend/node_modules/.bin/esgenerate @@ -1 +1,16 @@ -../escodegen/bin/esgenerate.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../escodegen/bin/esgenerate.js" "$@" +else + exec node "$basedir/../escodegen/bin/esgenerate.js" "$@" +fi diff --git a/frontend/node_modules/.bin/eslint b/frontend/node_modules/.bin/eslint index 810e4bcb..d450ee1f 120000 --- a/frontend/node_modules/.bin/eslint +++ b/frontend/node_modules/.bin/eslint @@ -1 +1,16 @@ -../eslint/bin/eslint.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../eslint/bin/eslint.js" "$@" +else + exec node "$basedir/../eslint/bin/eslint.js" "$@" +fi diff --git a/frontend/node_modules/.bin/esparse b/frontend/node_modules/.bin/esparse index 7423b18b..601762ce 120000 --- a/frontend/node_modules/.bin/esparse +++ b/frontend/node_modules/.bin/esparse @@ -1 +1,16 @@ -../esprima/bin/esparse.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../esprima/bin/esparse.js" "$@" +else + exec node "$basedir/../esprima/bin/esparse.js" "$@" +fi diff --git a/frontend/node_modules/.bin/esvalidate b/frontend/node_modules/.bin/esvalidate index 16069eff..e2fee1f1 120000 --- a/frontend/node_modules/.bin/esvalidate +++ b/frontend/node_modules/.bin/esvalidate @@ -1 +1,16 @@ -../esprima/bin/esvalidate.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../esprima/bin/esvalidate.js" "$@" +else + exec node "$basedir/../esprima/bin/esvalidate.js" "$@" +fi diff --git a/frontend/node_modules/.bin/he b/frontend/node_modules/.bin/he index 2a8eb5e0..441322aa 120000 --- a/frontend/node_modules/.bin/he +++ b/frontend/node_modules/.bin/he @@ -1 +1,16 @@ -../he/bin/he \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../he/bin/he" "$@" +else + exec node "$basedir/../he/bin/he" "$@" +fi diff --git a/frontend/node_modules/.bin/html-minifier-terser b/frontend/node_modules/.bin/html-minifier-terser index bab06671..eb7032f4 120000 --- a/frontend/node_modules/.bin/html-minifier-terser +++ b/frontend/node_modules/.bin/html-minifier-terser @@ -1 +1,16 @@ -../html-minifier-terser/cli.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../html-minifier-terser/cli.js" "$@" +else + exec node "$basedir/../html-minifier-terser/cli.js" "$@" +fi diff --git a/frontend/node_modules/.bin/import-local-fixture b/frontend/node_modules/.bin/import-local-fixture index ff4b1048..3a654413 120000 --- a/frontend/node_modules/.bin/import-local-fixture +++ b/frontend/node_modules/.bin/import-local-fixture @@ -1 +1,16 @@ -../import-local/fixtures/cli.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../import-local/fixtures/cli.js" "$@" +else + exec node "$basedir/../import-local/fixtures/cli.js" "$@" +fi diff --git a/frontend/node_modules/.bin/is-docker b/frontend/node_modules/.bin/is-docker index 9896ba57..d18b9991 120000 --- a/frontend/node_modules/.bin/is-docker +++ b/frontend/node_modules/.bin/is-docker @@ -1 +1,16 @@ -../is-docker/cli.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../is-docker/cli.js" "$@" +else + exec node "$basedir/../is-docker/cli.js" "$@" +fi diff --git a/frontend/node_modules/.bin/jake b/frontend/node_modules/.bin/jake index 36267456..b92bfbad 120000 --- a/frontend/node_modules/.bin/jake +++ b/frontend/node_modules/.bin/jake @@ -1 +1,16 @@ -../jake/bin/cli.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../jake/bin/cli.js" "$@" +else + exec node "$basedir/../jake/bin/cli.js" "$@" +fi diff --git a/frontend/node_modules/.bin/jest b/frontend/node_modules/.bin/jest index 61c18615..61b6f565 120000 --- a/frontend/node_modules/.bin/jest +++ b/frontend/node_modules/.bin/jest @@ -1 +1,16 @@ -../jest/bin/jest.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../jest/bin/jest.js" "$@" +else + exec node "$basedir/../jest/bin/jest.js" "$@" +fi diff --git a/frontend/node_modules/.bin/jiti b/frontend/node_modules/.bin/jiti index 031ee3fd..4b9f4a77 120000 --- a/frontend/node_modules/.bin/jiti +++ b/frontend/node_modules/.bin/jiti @@ -1 +1,16 @@ -../jiti/bin/jiti.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../jiti/bin/jiti.js" "$@" +else + exec node "$basedir/../jiti/bin/jiti.js" "$@" +fi diff --git a/frontend/node_modules/.bin/js-yaml b/frontend/node_modules/.bin/js-yaml index 9dbd010d..82416ef1 120000 --- a/frontend/node_modules/.bin/js-yaml +++ b/frontend/node_modules/.bin/js-yaml @@ -1 +1,16 @@ -../js-yaml/bin/js-yaml.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../js-yaml/bin/js-yaml.js" "$@" +else + exec node "$basedir/../js-yaml/bin/js-yaml.js" "$@" +fi diff --git a/frontend/node_modules/.bin/jsesc b/frontend/node_modules/.bin/jsesc index 7237604c..879c4133 120000 --- a/frontend/node_modules/.bin/jsesc +++ b/frontend/node_modules/.bin/jsesc @@ -1 +1,16 @@ -../jsesc/bin/jsesc \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../jsesc/bin/jsesc" "$@" +else + exec node "$basedir/../jsesc/bin/jsesc" "$@" +fi diff --git a/frontend/node_modules/.bin/json5 b/frontend/node_modules/.bin/json5 index 217f3798..abf72a4e 120000 --- a/frontend/node_modules/.bin/json5 +++ b/frontend/node_modules/.bin/json5 @@ -1 +1,16 @@ -../json5/lib/cli.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../json5/lib/cli.js" "$@" +else + exec node "$basedir/../json5/lib/cli.js" "$@" +fi diff --git a/frontend/node_modules/.bin/loose-envify b/frontend/node_modules/.bin/loose-envify index ed9009c5..076f91b1 120000 --- a/frontend/node_modules/.bin/loose-envify +++ b/frontend/node_modules/.bin/loose-envify @@ -1 +1,16 @@ -../loose-envify/cli.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../loose-envify/cli.js" "$@" +else + exec node "$basedir/../loose-envify/cli.js" "$@" +fi diff --git a/frontend/node_modules/.bin/lz-string b/frontend/node_modules/.bin/lz-string index 14bd70d2..4d961b0a 120000 --- a/frontend/node_modules/.bin/lz-string +++ b/frontend/node_modules/.bin/lz-string @@ -1 +1,16 @@ -../lz-string/bin/bin.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../lz-string/bin/bin.js" "$@" +else + exec node "$basedir/../lz-string/bin/bin.js" "$@" +fi diff --git a/frontend/node_modules/.bin/mime b/frontend/node_modules/.bin/mime index fbb7ee0e..7751de3c 120000 --- a/frontend/node_modules/.bin/mime +++ b/frontend/node_modules/.bin/mime @@ -1 +1,16 @@ -../mime/cli.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../mime/cli.js" "$@" +else + exec node "$basedir/../mime/cli.js" "$@" +fi diff --git a/frontend/node_modules/.bin/mkdirp b/frontend/node_modules/.bin/mkdirp index 017896ce..1ab9c81a 120000 --- a/frontend/node_modules/.bin/mkdirp +++ b/frontend/node_modules/.bin/mkdirp @@ -1 +1,16 @@ -../mkdirp/bin/cmd.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../mkdirp/bin/cmd.js" "$@" +else + exec node "$basedir/../mkdirp/bin/cmd.js" "$@" +fi diff --git a/frontend/node_modules/.bin/multicast-dns b/frontend/node_modules/.bin/multicast-dns index 801fc526..8ac1ffb2 120000 --- a/frontend/node_modules/.bin/multicast-dns +++ b/frontend/node_modules/.bin/multicast-dns @@ -1 +1,16 @@ -../multicast-dns/cli.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../multicast-dns/cli.js" "$@" +else + exec node "$basedir/../multicast-dns/cli.js" "$@" +fi diff --git a/frontend/node_modules/.bin/nanoid b/frontend/node_modules/.bin/nanoid index e2be547b..46220bdb 120000 --- a/frontend/node_modules/.bin/nanoid +++ b/frontend/node_modules/.bin/nanoid @@ -1 +1,16 @@ -../nanoid/bin/nanoid.cjs \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../nanoid/bin/nanoid.cjs" "$@" +else + exec node "$basedir/../nanoid/bin/nanoid.cjs" "$@" +fi diff --git a/frontend/node_modules/.bin/node-which b/frontend/node_modules/.bin/node-which index 6f8415ec..b49b03f7 120000 --- a/frontend/node_modules/.bin/node-which +++ b/frontend/node_modules/.bin/node-which @@ -1 +1,16 @@ -../which/bin/node-which \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../which/bin/node-which" "$@" +else + exec node "$basedir/../which/bin/node-which" "$@" +fi diff --git a/frontend/node_modules/.bin/parser b/frontend/node_modules/.bin/parser index ce7bf97e..7696ad41 120000 --- a/frontend/node_modules/.bin/parser +++ b/frontend/node_modules/.bin/parser @@ -1 +1,16 @@ -../@babel/parser/bin/babel-parser.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../@babel/parser/bin/babel-parser.js" "$@" +else + exec node "$basedir/../@babel/parser/bin/babel-parser.js" "$@" +fi diff --git a/frontend/node_modules/.bin/react-scripts b/frontend/node_modules/.bin/react-scripts index fe0fb709..889a14f7 120000 --- a/frontend/node_modules/.bin/react-scripts +++ b/frontend/node_modules/.bin/react-scripts @@ -1 +1,16 @@ -../react-scripts/bin/react-scripts.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../react-scripts/bin/react-scripts.js" "$@" +else + exec node "$basedir/../react-scripts/bin/react-scripts.js" "$@" +fi diff --git a/frontend/node_modules/.bin/regjsparser b/frontend/node_modules/.bin/regjsparser index 91cec777..3e923c7a 120000 --- a/frontend/node_modules/.bin/regjsparser +++ b/frontend/node_modules/.bin/regjsparser @@ -1 +1,16 @@ -../regjsparser/bin/parser \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../regjsparser/bin/parser" "$@" +else + exec node "$basedir/../regjsparser/bin/parser" "$@" +fi diff --git a/frontend/node_modules/.bin/resolve b/frontend/node_modules/.bin/resolve index b6afda6c..c043cba0 120000 --- a/frontend/node_modules/.bin/resolve +++ b/frontend/node_modules/.bin/resolve @@ -1 +1,16 @@ -../resolve/bin/resolve \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../resolve/bin/resolve" "$@" +else + exec node "$basedir/../resolve/bin/resolve" "$@" +fi diff --git a/frontend/node_modules/.bin/rimraf b/frontend/node_modules/.bin/rimraf index 4cd49a49..6d6240a8 120000 --- a/frontend/node_modules/.bin/rimraf +++ b/frontend/node_modules/.bin/rimraf @@ -1 +1,16 @@ -../rimraf/bin.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../rimraf/bin.js" "$@" +else + exec node "$basedir/../rimraf/bin.js" "$@" +fi diff --git a/frontend/node_modules/.bin/rollup b/frontend/node_modules/.bin/rollup index 5939621c..998fc164 120000 --- a/frontend/node_modules/.bin/rollup +++ b/frontend/node_modules/.bin/rollup @@ -1 +1,16 @@ -../rollup/dist/bin/rollup \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../rollup/dist/bin/rollup" "$@" +else + exec node "$basedir/../rollup/dist/bin/rollup" "$@" +fi diff --git a/frontend/node_modules/.bin/semver b/frontend/node_modules/.bin/semver index 5aaadf42..97c53279 120000 --- a/frontend/node_modules/.bin/semver +++ b/frontend/node_modules/.bin/semver @@ -1 +1,16 @@ -../semver/bin/semver.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../semver/bin/semver.js" "$@" +else + exec node "$basedir/../semver/bin/semver.js" "$@" +fi diff --git a/frontend/node_modules/.bin/sucrase b/frontend/node_modules/.bin/sucrase index 0ac7e775..6c58a2e4 120000 --- a/frontend/node_modules/.bin/sucrase +++ b/frontend/node_modules/.bin/sucrase @@ -1 +1,16 @@ -../sucrase/bin/sucrase \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../sucrase/bin/sucrase" "$@" +else + exec node "$basedir/../sucrase/bin/sucrase" "$@" +fi diff --git a/frontend/node_modules/.bin/sucrase-node b/frontend/node_modules/.bin/sucrase-node index 8b96fae2..fb3bb6c2 120000 --- a/frontend/node_modules/.bin/sucrase-node +++ b/frontend/node_modules/.bin/sucrase-node @@ -1 +1,16 @@ -../sucrase/bin/sucrase-node \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../sucrase/bin/sucrase-node" "$@" +else + exec node "$basedir/../sucrase/bin/sucrase-node" "$@" +fi diff --git a/frontend/node_modules/.bin/svgo b/frontend/node_modules/.bin/svgo index d6a228b7..15092ee6 120000 --- a/frontend/node_modules/.bin/svgo +++ b/frontend/node_modules/.bin/svgo @@ -1 +1,16 @@ -../svgo/bin/svgo \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../svgo/bin/svgo" "$@" +else + exec node "$basedir/../svgo/bin/svgo" "$@" +fi diff --git a/frontend/node_modules/.bin/tailwind b/frontend/node_modules/.bin/tailwind index d4977975..e475d32e 120000 --- a/frontend/node_modules/.bin/tailwind +++ b/frontend/node_modules/.bin/tailwind @@ -1 +1,16 @@ -../tailwindcss/lib/cli.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../tailwindcss/lib/cli.js" "$@" +else + exec node "$basedir/../tailwindcss/lib/cli.js" "$@" +fi diff --git a/frontend/node_modules/.bin/tailwindcss b/frontend/node_modules/.bin/tailwindcss index d4977975..e475d32e 120000 --- a/frontend/node_modules/.bin/tailwindcss +++ b/frontend/node_modules/.bin/tailwindcss @@ -1 +1,16 @@ -../tailwindcss/lib/cli.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../tailwindcss/lib/cli.js" "$@" +else + exec node "$basedir/../tailwindcss/lib/cli.js" "$@" +fi diff --git a/frontend/node_modules/.bin/terser b/frontend/node_modules/.bin/terser index 0792ff47..84565460 120000 --- a/frontend/node_modules/.bin/terser +++ b/frontend/node_modules/.bin/terser @@ -1 +1,16 @@ -../terser/bin/terser \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../terser/bin/terser" "$@" +else + exec node "$basedir/../terser/bin/terser" "$@" +fi diff --git a/frontend/node_modules/.bin/tsc b/frontend/node_modules/.bin/tsc index 0863208a..c4864b9a 120000 --- a/frontend/node_modules/.bin/tsc +++ b/frontend/node_modules/.bin/tsc @@ -1 +1,16 @@ -../typescript/bin/tsc \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../typescript/bin/tsc" "$@" +else + exec node "$basedir/../typescript/bin/tsc" "$@" +fi diff --git a/frontend/node_modules/.bin/tsserver b/frontend/node_modules/.bin/tsserver index f8f8f1a0..6c19ce3d 120000 --- a/frontend/node_modules/.bin/tsserver +++ b/frontend/node_modules/.bin/tsserver @@ -1 +1,16 @@ -../typescript/bin/tsserver \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../typescript/bin/tsserver" "$@" +else + exec node "$basedir/../typescript/bin/tsserver" "$@" +fi diff --git a/frontend/node_modules/.bin/update-browserslist-db b/frontend/node_modules/.bin/update-browserslist-db index b11e16f3..cced63c4 120000 --- a/frontend/node_modules/.bin/update-browserslist-db +++ b/frontend/node_modules/.bin/update-browserslist-db @@ -1 +1,16 @@ -../update-browserslist-db/cli.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../update-browserslist-db/cli.js" "$@" +else + exec node "$basedir/../update-browserslist-db/cli.js" "$@" +fi diff --git a/frontend/node_modules/.bin/uuid b/frontend/node_modules/.bin/uuid index 588f70ec..0c2d4696 120000 --- a/frontend/node_modules/.bin/uuid +++ b/frontend/node_modules/.bin/uuid @@ -1 +1,16 @@ -../uuid/dist/bin/uuid \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../uuid/dist/bin/uuid" "$@" +else + exec node "$basedir/../uuid/dist/bin/uuid" "$@" +fi diff --git a/frontend/node_modules/.bin/webpack b/frontend/node_modules/.bin/webpack index d462c1d1..8442160a 120000 --- a/frontend/node_modules/.bin/webpack +++ b/frontend/node_modules/.bin/webpack @@ -1 +1,16 @@ -../webpack/bin/webpack.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../webpack/bin/webpack.js" "$@" +else + exec node "$basedir/../webpack/bin/webpack.js" "$@" +fi diff --git a/frontend/node_modules/.bin/webpack-dev-server b/frontend/node_modules/.bin/webpack-dev-server index 242fe0a6..ab7ea9d7 120000 --- a/frontend/node_modules/.bin/webpack-dev-server +++ b/frontend/node_modules/.bin/webpack-dev-server @@ -1 +1,16 @@ -../webpack-dev-server/bin/webpack-dev-server.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../webpack-dev-server/bin/webpack-dev-server.js" "$@" +else + exec node "$basedir/../webpack-dev-server/bin/webpack-dev-server.js" "$@" +fi diff --git a/frontend/node_modules/@babel/core/node_modules/.bin/semver b/frontend/node_modules/@babel/core/node_modules/.bin/semver index 5aaadf42..97c53279 120000 --- a/frontend/node_modules/@babel/core/node_modules/.bin/semver +++ b/frontend/node_modules/@babel/core/node_modules/.bin/semver @@ -1 +1,16 @@ -../semver/bin/semver.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../semver/bin/semver.js" "$@" +else + exec node "$basedir/../semver/bin/semver.js" "$@" +fi diff --git a/frontend/node_modules/@babel/eslint-parser/node_modules/.bin/semver b/frontend/node_modules/@babel/eslint-parser/node_modules/.bin/semver index 5aaadf42..97c53279 120000 --- a/frontend/node_modules/@babel/eslint-parser/node_modules/.bin/semver +++ b/frontend/node_modules/@babel/eslint-parser/node_modules/.bin/semver @@ -1 +1,16 @@ -../semver/bin/semver.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../semver/bin/semver.js" "$@" +else + exec node "$basedir/../semver/bin/semver.js" "$@" +fi diff --git a/frontend/node_modules/@babel/helper-compilation-targets/node_modules/.bin/semver b/frontend/node_modules/@babel/helper-compilation-targets/node_modules/.bin/semver index 5aaadf42..97c53279 120000 --- a/frontend/node_modules/@babel/helper-compilation-targets/node_modules/.bin/semver +++ b/frontend/node_modules/@babel/helper-compilation-targets/node_modules/.bin/semver @@ -1 +1,16 @@ -../semver/bin/semver.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../semver/bin/semver.js" "$@" +else + exec node "$basedir/../semver/bin/semver.js" "$@" +fi diff --git a/frontend/node_modules/@babel/helper-create-class-features-plugin/node_modules/.bin/semver b/frontend/node_modules/@babel/helper-create-class-features-plugin/node_modules/.bin/semver index 5aaadf42..97c53279 120000 --- a/frontend/node_modules/@babel/helper-create-class-features-plugin/node_modules/.bin/semver +++ b/frontend/node_modules/@babel/helper-create-class-features-plugin/node_modules/.bin/semver @@ -1 +1,16 @@ -../semver/bin/semver.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../semver/bin/semver.js" "$@" +else + exec node "$basedir/../semver/bin/semver.js" "$@" +fi diff --git a/frontend/node_modules/@babel/helper-create-regexp-features-plugin/node_modules/.bin/semver b/frontend/node_modules/@babel/helper-create-regexp-features-plugin/node_modules/.bin/semver index 5aaadf42..97c53279 120000 --- a/frontend/node_modules/@babel/helper-create-regexp-features-plugin/node_modules/.bin/semver +++ b/frontend/node_modules/@babel/helper-create-regexp-features-plugin/node_modules/.bin/semver @@ -1 +1,16 @@ -../semver/bin/semver.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../semver/bin/semver.js" "$@" +else + exec node "$basedir/../semver/bin/semver.js" "$@" +fi diff --git a/frontend/node_modules/@babel/plugin-transform-runtime/node_modules/.bin/semver b/frontend/node_modules/@babel/plugin-transform-runtime/node_modules/.bin/semver index 5aaadf42..97c53279 120000 --- a/frontend/node_modules/@babel/plugin-transform-runtime/node_modules/.bin/semver +++ b/frontend/node_modules/@babel/plugin-transform-runtime/node_modules/.bin/semver @@ -1 +1,16 @@ -../semver/bin/semver.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../semver/bin/semver.js" "$@" +else + exec node "$basedir/../semver/bin/semver.js" "$@" +fi diff --git a/frontend/node_modules/@babel/preset-env/node_modules/.bin/semver b/frontend/node_modules/@babel/preset-env/node_modules/.bin/semver index 5aaadf42..97c53279 120000 --- a/frontend/node_modules/@babel/preset-env/node_modules/.bin/semver +++ b/frontend/node_modules/@babel/preset-env/node_modules/.bin/semver @@ -1 +1,16 @@ -../semver/bin/semver.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../semver/bin/semver.js" "$@" +else + exec node "$basedir/../semver/bin/semver.js" "$@" +fi diff --git a/frontend/node_modules/@eslint/eslintrc/node_modules/.bin/js-yaml b/frontend/node_modules/@eslint/eslintrc/node_modules/.bin/js-yaml index 9dbd010d..82416ef1 120000 --- a/frontend/node_modules/@eslint/eslintrc/node_modules/.bin/js-yaml +++ b/frontend/node_modules/@eslint/eslintrc/node_modules/.bin/js-yaml @@ -1 +1,16 @@ -../js-yaml/bin/js-yaml.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../js-yaml/bin/js-yaml.js" "$@" +else + exec node "$basedir/../js-yaml/bin/js-yaml.js" "$@" +fi diff --git a/frontend/node_modules/acorn-globals/node_modules/.bin/acorn b/frontend/node_modules/acorn-globals/node_modules/.bin/acorn index cf767603..679bd163 120000 --- a/frontend/node_modules/acorn-globals/node_modules/.bin/acorn +++ b/frontend/node_modules/acorn-globals/node_modules/.bin/acorn @@ -1 +1,16 @@ -../acorn/bin/acorn \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../acorn/bin/acorn" "$@" +else + exec node "$basedir/../acorn/bin/acorn" "$@" +fi diff --git a/frontend/node_modules/babel-plugin-polyfill-corejs2/node_modules/.bin/semver b/frontend/node_modules/babel-plugin-polyfill-corejs2/node_modules/.bin/semver index 5aaadf42..97c53279 120000 --- a/frontend/node_modules/babel-plugin-polyfill-corejs2/node_modules/.bin/semver +++ b/frontend/node_modules/babel-plugin-polyfill-corejs2/node_modules/.bin/semver @@ -1 +1,16 @@ -../semver/bin/semver.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../semver/bin/semver.js" "$@" +else + exec node "$basedir/../semver/bin/semver.js" "$@" +fi diff --git a/frontend/node_modules/eslint-plugin-import/node_modules/.bin/semver b/frontend/node_modules/eslint-plugin-import/node_modules/.bin/semver index 5aaadf42..97c53279 120000 --- a/frontend/node_modules/eslint-plugin-import/node_modules/.bin/semver +++ b/frontend/node_modules/eslint-plugin-import/node_modules/.bin/semver @@ -1 +1,16 @@ -../semver/bin/semver.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../semver/bin/semver.js" "$@" +else + exec node "$basedir/../semver/bin/semver.js" "$@" +fi diff --git a/frontend/node_modules/eslint-plugin-react/node_modules/.bin/resolve b/frontend/node_modules/eslint-plugin-react/node_modules/.bin/resolve index b6afda6c..c043cba0 120000 --- a/frontend/node_modules/eslint-plugin-react/node_modules/.bin/resolve +++ b/frontend/node_modules/eslint-plugin-react/node_modules/.bin/resolve @@ -1 +1,16 @@ -../resolve/bin/resolve \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../resolve/bin/resolve" "$@" +else + exec node "$basedir/../resolve/bin/resolve" "$@" +fi diff --git a/frontend/node_modules/eslint-plugin-react/node_modules/.bin/semver b/frontend/node_modules/eslint-plugin-react/node_modules/.bin/semver index 5aaadf42..97c53279 120000 --- a/frontend/node_modules/eslint-plugin-react/node_modules/.bin/semver +++ b/frontend/node_modules/eslint-plugin-react/node_modules/.bin/semver @@ -1 +1,16 @@ -../semver/bin/semver.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../semver/bin/semver.js" "$@" +else + exec node "$basedir/../semver/bin/semver.js" "$@" +fi diff --git a/frontend/node_modules/eslint/node_modules/.bin/js-yaml b/frontend/node_modules/eslint/node_modules/.bin/js-yaml index 9dbd010d..82416ef1 120000 --- a/frontend/node_modules/eslint/node_modules/.bin/js-yaml +++ b/frontend/node_modules/eslint/node_modules/.bin/js-yaml @@ -1 +1,16 @@ -../js-yaml/bin/js-yaml.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../js-yaml/bin/js-yaml.js" "$@" +else + exec node "$basedir/../js-yaml/bin/js-yaml.js" "$@" +fi diff --git a/frontend/node_modules/global-prefix/node_modules/.bin/which b/frontend/node_modules/global-prefix/node_modules/.bin/which index f62471c8..cf23e656 120000 --- a/frontend/node_modules/global-prefix/node_modules/.bin/which +++ b/frontend/node_modules/global-prefix/node_modules/.bin/which @@ -1 +1,16 @@ -../which/bin/which \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../which/bin/which" "$@" +else + exec node "$basedir/../which/bin/which" "$@" +fi diff --git a/frontend/node_modules/istanbul-lib-instrument/node_modules/.bin/semver b/frontend/node_modules/istanbul-lib-instrument/node_modules/.bin/semver index 5aaadf42..97c53279 120000 --- a/frontend/node_modules/istanbul-lib-instrument/node_modules/.bin/semver +++ b/frontend/node_modules/istanbul-lib-instrument/node_modules/.bin/semver @@ -1 +1,16 @@ -../semver/bin/semver.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../semver/bin/semver.js" "$@" +else + exec node "$basedir/../semver/bin/semver.js" "$@" +fi diff --git a/frontend/node_modules/jsonpath/node_modules/.bin/esparse b/frontend/node_modules/jsonpath/node_modules/.bin/esparse index 7423b18b..601762ce 120000 --- a/frontend/node_modules/jsonpath/node_modules/.bin/esparse +++ b/frontend/node_modules/jsonpath/node_modules/.bin/esparse @@ -1 +1,16 @@ -../esprima/bin/esparse.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../esprima/bin/esparse.js" "$@" +else + exec node "$basedir/../esprima/bin/esparse.js" "$@" +fi diff --git a/frontend/node_modules/jsonpath/node_modules/.bin/esvalidate b/frontend/node_modules/jsonpath/node_modules/.bin/esvalidate index 16069eff..e2fee1f1 120000 --- a/frontend/node_modules/jsonpath/node_modules/.bin/esvalidate +++ b/frontend/node_modules/jsonpath/node_modules/.bin/esvalidate @@ -1 +1,16 @@ -../esprima/bin/esvalidate.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../esprima/bin/esvalidate.js" "$@" +else + exec node "$basedir/../esprima/bin/esvalidate.js" "$@" +fi diff --git a/frontend/node_modules/make-dir/node_modules/.bin/semver b/frontend/node_modules/make-dir/node_modules/.bin/semver index 5aaadf42..97c53279 120000 --- a/frontend/node_modules/make-dir/node_modules/.bin/semver +++ b/frontend/node_modules/make-dir/node_modules/.bin/semver @@ -1 +1,16 @@ -../semver/bin/semver.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../semver/bin/semver.js" "$@" +else + exec node "$basedir/../semver/bin/semver.js" "$@" +fi diff --git a/frontend/node_modules/postcss-load-config/node_modules/.bin/yaml b/frontend/node_modules/postcss-load-config/node_modules/.bin/yaml index 03683247..c68b081f 120000 --- a/frontend/node_modules/postcss-load-config/node_modules/.bin/yaml +++ b/frontend/node_modules/postcss-load-config/node_modules/.bin/yaml @@ -1 +1,16 @@ -../yaml/bin.mjs \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../yaml/bin.mjs" "$@" +else + exec node "$basedir/../yaml/bin.mjs" "$@" +fi diff --git a/frontend/node_modules/postcss-svgo/node_modules/.bin/svgo b/frontend/node_modules/postcss-svgo/node_modules/.bin/svgo index d6a228b7..15092ee6 120000 --- a/frontend/node_modules/postcss-svgo/node_modules/.bin/svgo +++ b/frontend/node_modules/postcss-svgo/node_modules/.bin/svgo @@ -1 +1,16 @@ -../svgo/bin/svgo \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../svgo/bin/svgo" "$@" +else + exec node "$basedir/../svgo/bin/svgo" "$@" +fi diff --git a/frontend/node_modules/regjsparser/node_modules/.bin/jsesc b/frontend/node_modules/regjsparser/node_modules/.bin/jsesc index 7237604c..879c4133 120000 --- a/frontend/node_modules/regjsparser/node_modules/.bin/jsesc +++ b/frontend/node_modules/regjsparser/node_modules/.bin/jsesc @@ -1 +1,16 @@ -../jsesc/bin/jsesc \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../jsesc/bin/jsesc" "$@" +else + exec node "$basedir/../jsesc/bin/jsesc" "$@" +fi diff --git a/frontend/node_modules/static-eval/node_modules/.bin/escodegen b/frontend/node_modules/static-eval/node_modules/.bin/escodegen index 01a7c325..1dbc1f02 120000 --- a/frontend/node_modules/static-eval/node_modules/.bin/escodegen +++ b/frontend/node_modules/static-eval/node_modules/.bin/escodegen @@ -1 +1,16 @@ -../escodegen/bin/escodegen.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../escodegen/bin/escodegen.js" "$@" +else + exec node "$basedir/../escodegen/bin/escodegen.js" "$@" +fi diff --git a/frontend/node_modules/static-eval/node_modules/.bin/esgenerate b/frontend/node_modules/static-eval/node_modules/.bin/esgenerate index 7d0293e6..8633c745 120000 --- a/frontend/node_modules/static-eval/node_modules/.bin/esgenerate +++ b/frontend/node_modules/static-eval/node_modules/.bin/esgenerate @@ -1 +1,16 @@ -../escodegen/bin/esgenerate.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../escodegen/bin/esgenerate.js" "$@" +else + exec node "$basedir/../escodegen/bin/esgenerate.js" "$@" +fi diff --git a/frontend/node_modules/sucrase/node_modules/.bin/glob b/frontend/node_modules/sucrase/node_modules/.bin/glob index 85c9c1db..6fbc4bb8 120000 --- a/frontend/node_modules/sucrase/node_modules/.bin/glob +++ b/frontend/node_modules/sucrase/node_modules/.bin/glob @@ -1 +1,16 @@ -../glob/dist/esm/bin.mjs \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../glob/dist/esm/bin.mjs" "$@" +else + exec node "$basedir/../glob/dist/esm/bin.mjs" "$@" +fi diff --git a/frontend/node_modules/tsconfig-paths/node_modules/.bin/json5 b/frontend/node_modules/tsconfig-paths/node_modules/.bin/json5 index 217f3798..abf72a4e 120000 --- a/frontend/node_modules/tsconfig-paths/node_modules/.bin/json5 +++ b/frontend/node_modules/tsconfig-paths/node_modules/.bin/json5 @@ -1 +1,16 @@ -../json5/lib/cli.js \ No newline at end of file +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../json5/lib/cli.js" "$@" +else + exec node "$basedir/../json5/lib/cli.js" "$@" +fi diff --git a/frontend/smallgame/2048/controls.js b/frontend/smallgame/2048/controls.js deleted file mode 100755 index 8def4b81..00000000 --- a/frontend/smallgame/2048/controls.js +++ /dev/null @@ -1,537 +0,0 @@ -// 游戏控制模块 - 处理键盘和触摸输入 -class GameControls { - constructor() { - this.touchStartX = 0; - this.touchStartY = 0; - this.touchEndX = 0; - this.touchEndY = 0; - this.minSwipeDistance = 30; // 最小滑动距离 - this.isGameActive = true; - - this.initializeControls(); - } - - initializeControls() { - // 键盘控制 - this.initKeyboardControls(); - - // 触摸控制 - this.initTouchControls(); - - // 鼠标控制(用于电脑端测试) - this.initMouseControls(); - - // 防止页面滚动 - this.preventScrolling(); - } - - initKeyboardControls() { - document.addEventListener('keydown', (e) => { - if (!this.isGameActive || !window.game2048) { - console.log('Game not ready:', { isGameActive: this.isGameActive, game2048: !!window.game2048 }); - return; - } - - // 防止默认行为 - const preventKeys = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'w', 'a', 's', 'd', 'W', 'A', 'S', 'D']; - if (preventKeys.includes(e.key)) { - e.preventDefault(); - } - - switch (e.key) { - case 'ArrowUp': - case 'w': - case 'W': - window.game2048.move('up'); - break; - case 'ArrowDown': - case 's': - case 'S': - window.game2048.move('down'); - break; - case 'ArrowLeft': - case 'a': - case 'A': - window.game2048.move('left'); - break; - case 'ArrowRight': - case 'd': - case 'D': - window.game2048.move('right'); - break; - case 'r': - case 'R': - // R键重新开始游戏 - window.game2048.restart(); - break; - case 'Escape': - // ESC键暂停/继续游戏 - this.togglePause(); - break; - } - }); - } - - initTouchControls() { - const gameContainer = document.querySelector('.game-container'); - - // 触摸开始 - gameContainer.addEventListener('touchstart', (e) => { - if (!this.isGameActive) return; - - e.preventDefault(); - const touch = e.touches[0]; - this.touchStartX = touch.clientX; - this.touchStartY = touch.clientY; - }, { passive: false }); - - // 触摸移动(可选:显示滑动方向提示) - gameContainer.addEventListener('touchmove', (e) => { - e.preventDefault(); - }, { passive: false }); - - // 触摸结束 - gameContainer.addEventListener('touchend', (e) => { - if (!this.isGameActive || !window.game2048) return; - - e.preventDefault(); - const touch = e.changedTouches[0]; - this.touchEndX = touch.clientX; - this.touchEndY = touch.clientY; - - this.handleSwipe(); - }, { passive: false }); - - // 触摸取消 - gameContainer.addEventListener('touchcancel', (e) => { - e.preventDefault(); - this.resetTouch(); - }, { passive: false }); - } - - initMouseControls() { - const gameContainer = document.querySelector('.game-container'); - let isMouseDown = false; - let mouseStartX = 0; - let mouseStartY = 0; - - // 鼠标按下 - gameContainer.addEventListener('mousedown', (e) => { - if (!this.isGameActive) return; - - isMouseDown = true; - mouseStartX = e.clientX; - mouseStartY = e.clientY; - e.preventDefault(); - }); - - // 鼠标释放 - gameContainer.addEventListener('mouseup', (e) => { - if (!this.isGameActive || !isMouseDown || !window.game2048) return; - - isMouseDown = false; - const mouseEndX = e.clientX; - const mouseEndY = e.clientY; - - // 使用鼠标坐标模拟触摸 - this.touchStartX = mouseStartX; - this.touchStartY = mouseStartY; - this.touchEndX = mouseEndX; - this.touchEndY = mouseEndY; - - this.handleSwipe(); - e.preventDefault(); - }); - - // 鼠标离开游戏区域 - gameContainer.addEventListener('mouseleave', () => { - isMouseDown = false; - }); - - // 防止右键菜单 - gameContainer.addEventListener('contextmenu', (e) => { - e.preventDefault(); - }); - } - - handleSwipe() { - const deltaX = this.touchEndX - this.touchStartX; - const deltaY = this.touchEndY - this.touchStartY; - const absDeltaX = Math.abs(deltaX); - const absDeltaY = Math.abs(deltaY); - - // 检查是否达到最小滑动距离 - if (Math.max(absDeltaX, absDeltaY) < this.minSwipeDistance) { - this.resetTouch(); - return; - } - - // 确定滑动方向 - let direction = null; - - if (absDeltaX > absDeltaY) { - // 水平滑动 - direction = deltaX > 0 ? 'right' : 'left'; - } else { - // 垂直滑动 - direction = deltaY > 0 ? 'down' : 'up'; - } - - // 执行移动 - if (direction && window.game2048) { - window.game2048.move(direction); - - // 添加触觉反馈(如果支持) - this.addHapticFeedback(); - - // 添加视觉反馈 - this.addVisualFeedback(direction); - } - - this.resetTouch(); - } - - resetTouch() { - this.touchStartX = 0; - this.touchStartY = 0; - this.touchEndX = 0; - this.touchEndY = 0; - } - - addHapticFeedback() { - // 添加触觉反馈(仅在支持的设备上) - if (navigator.vibrate) { - navigator.vibrate(50); // 50ms的轻微震动 - } - } - - addVisualFeedback(direction) { - // 添加方向指示的视觉反馈 - const gameContainer = document.querySelector('.game-container'); - const feedback = document.createElement('div'); - - feedback.className = 'swipe-feedback'; - feedback.textContent = this.getDirectionArrow(direction); - - // 设置样式 - feedback.style.cssText = ` - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - font-size: 48px; - color: rgba(255, 255, 255, 0.8); - pointer-events: none; - z-index: 1000; - animation: swipeFeedback 0.3s ease-out; - `; - - gameContainer.appendChild(feedback); - - // 添加动画样式(如果不存在) - if (!document.getElementById('swipe-feedback-styles')) { - const style = document.createElement('style'); - style.id = 'swipe-feedback-styles'; - style.textContent = ` - @keyframes swipeFeedback { - 0% { - opacity: 0; - transform: translate(-50%, -50%) scale(0.5); - } - 50% { - opacity: 1; - transform: translate(-50%, -50%) scale(1.2); - } - 100% { - opacity: 0; - transform: translate(-50%, -50%) scale(1); - } - } - `; - document.head.appendChild(style); - } - - // 移除反馈元素 - setTimeout(() => { - if (feedback.parentNode) { - feedback.remove(); - } - }, 300); - } - - getDirectionArrow(direction) { - const arrows = { - 'up': '↑', - 'down': '↓', - 'left': '←', - 'right': '→' - }; - return arrows[direction] || ''; - } - - preventScrolling() { - // 防止页面滚动,特别是在移动设备上 - document.addEventListener('touchmove', (e) => { - // 只在游戏容器内防止滚动 - const gameContainer = document.querySelector('.game-container'); - if (gameContainer && gameContainer.contains(e.target)) { - e.preventDefault(); - } - }, { passive: false }); - - // 防止双击缩放 - document.addEventListener('touchstart', (e) => { - if (e.touches.length > 1) { - e.preventDefault(); - } - }, { passive: false }); - - // 防止长按选择文本 - document.addEventListener('selectstart', (e) => { - const gameContainer = document.querySelector('.game-container'); - if (gameContainer && gameContainer.contains(e.target)) { - e.preventDefault(); - } - }); - } - - togglePause() { - this.isGameActive = !this.isGameActive; - - const pauseOverlay = document.getElementById('pause-overlay') || this.createPauseOverlay(); - - if (this.isGameActive) { - pauseOverlay.style.display = 'none'; - // 恢复计时器 - if (window.game2048 && window.game2048.stats.startTime) { - const pausedTime = Date.now() - window.game2048.pauseStartTime; - window.game2048.stats.startTime += pausedTime; - } - } else { - pauseOverlay.style.display = 'flex'; - // 记录暂停时间 - if (window.game2048) { - window.game2048.pauseStartTime = Date.now(); - } - } - } - - createPauseOverlay() { - const overlay = document.createElement('div'); - overlay.id = 'pause-overlay'; - overlay.innerHTML = ` -
      -

      游戏暂停

      -

      按ESC键或点击继续游戏

      - -
      - `; - - overlay.style.cssText = ` - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: rgba(0, 0, 0, 0.8); - display: none; - justify-content: center; - align-items: center; - z-index: 10000; - backdrop-filter: blur(5px); - `; - - const pauseContent = overlay.querySelector('.pause-content'); - pauseContent.style.cssText = ` - background: white; - padding: 40px; - border-radius: 15px; - text-align: center; - box-shadow: 0 10px 30px rgba(0,0,0,0.3); - `; - - const resumeBtn = overlay.querySelector('.resume-btn'); - resumeBtn.style.cssText = ` - background: linear-gradient(45deg, #4ecdc4, #44a08d); - color: white; - border: none; - padding: 12px 24px; - border-radius: 25px; - font-size: 16px; - font-weight: bold; - cursor: pointer; - margin-top: 20px; - transition: all 0.3s ease; - `; - - // 继续游戏按钮事件 - resumeBtn.addEventListener('click', () => { - this.togglePause(); - }); - - // 点击背景继续游戏 - overlay.addEventListener('click', (e) => { - if (e.target === overlay) { - this.togglePause(); - } - }); - - document.body.appendChild(overlay); - return overlay; - } - - // 禁用控制(游戏结束时调用) - disable() { - this.isGameActive = false; - } - - // 启用控制(游戏开始时调用) - enable() { - this.isGameActive = true; - } - - // 显示控制提示 - showControlHints() { - const hints = document.createElement('div'); - hints.className = 'control-hints'; - hints.innerHTML = ` -
      -

      操作说明

      -
      -

      📱 手机操作

      -

      在游戏区域滑动手指移动方块

      -
      - 👆 上滑 - 👇 下滑 - 👈 左滑 - 👉 右滑 -
      -
      -
      -

      ⌨️ 键盘操作

      -
      -
      - - W - 上移 -
      -
      - - S - 下移 -
      -
      - - A - 左移 -
      -
      - - D - 右移 -
      -
      - R - 重新开始 -
      -
      - ESC - 暂停/继续 -
      -
      -
      - -
      - `; - - // 添加样式 - hints.style.cssText = ` - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: rgba(0, 0, 0, 0.8); - display: flex; - justify-content: center; - align-items: center; - z-index: 10000; - backdrop-filter: blur(5px); - `; - - document.body.appendChild(hints); - - // 关闭按钮事件 - hints.querySelector('.close-hints').addEventListener('click', () => { - hints.remove(); - }); - - // 点击背景关闭 - hints.addEventListener('click', (e) => { - if (e.target === hints) { - hints.remove(); - } - }); - } -} - -// 创建全局控制实例 -let gameControls; - -// 页面加载完成后初始化控制 -document.addEventListener('DOMContentLoaded', () => { - // 等待游戏对象初始化完成 - const initControls = () => { - if (window.game2048) { - gameControls = new GameControls(); - console.log('Game controls initialized successfully'); - - // 创建帮助按钮 - createHelpButton(); - } else { - console.log('Waiting for game2048 to initialize...'); - setTimeout(initControls, 100); - } - }; - - initControls(); -}); - -// 创建帮助按钮函数 -function createHelpButton() { - const helpBtn = document.createElement('button'); - helpBtn.textContent = '❓'; - helpBtn.title = '操作说明'; - helpBtn.style.cssText = ` - position: fixed; - top: 20px; - right: 20px; - width: 50px; - height: 50px; - border-radius: 50%; - background: rgba(255, 255, 255, 0.9); - border: none; - font-size: 20px; - cursor: pointer; - box-shadow: 0 4px 12px rgba(0,0,0,0.2); - z-index: 1000; - transition: all 0.3s ease; - `; - - helpBtn.addEventListener('click', () => { - gameControls.showControlHints(); - }); - - helpBtn.addEventListener('mouseenter', () => { - helpBtn.style.transform = 'scale(1.1)'; - }); - - helpBtn.addEventListener('mouseleave', () => { - helpBtn.style.transform = 'scale(1)'; - }); - - document.body.appendChild(helpBtn); -} - -// 导出控制实例 -window.gameControls = gameControls; \ No newline at end of file diff --git a/frontend/smallgame/2048/game-logic.js b/frontend/smallgame/2048/game-logic.js deleted file mode 100755 index d442b5d0..00000000 --- a/frontend/smallgame/2048/game-logic.js +++ /dev/null @@ -1,424 +0,0 @@ -// 2048游戏核心逻辑 -class Game2048 { - constructor() { - this.size = 4; - this.grid = []; - this.score = 0; - this.bestScore = parseInt(localStorage.getItem('2048-best-score')) || 0; - this.gameWon = false; - this.gameOver = false; - this.moved = false; - - // 游戏统计数据 - this.stats = { - moves: 0, - startTime: null, - gameTime: 0, - maxTile: 2, - mergeCount: 0 - }; - - this.initializeGrid(); - this.updateDisplay(); - this.addRandomTile(); - this.addRandomTile(); - this.updateDisplay(); - - // 绑定事件 - this.bindEvents(); - - // 开始计时 - this.startTimer(); - } - - initializeGrid() { - this.grid = []; - for (let i = 0; i < this.size; i++) { - this.grid[i] = []; - for (let j = 0; j < this.size; j++) { - this.grid[i][j] = 0; - } - } - } - - addRandomTile() { - const emptyCells = []; - for (let i = 0; i < this.size; i++) { - for (let j = 0; j < this.size; j++) { - if (this.grid[i][j] === 0) { - emptyCells.push({x: i, y: j}); - } - } - } - - if (emptyCells.length > 0) { - const randomCell = emptyCells[Math.floor(Math.random() * emptyCells.length)]; - const value = Math.random() < 0.9 ? 2 : 4; - this.grid[randomCell.x][randomCell.y] = value; - - // 创建新方块动画 - this.createTileElement(randomCell.x, randomCell.y, value, true); - } - } - - createTileElement(x, y, value, isNew = false) { - const container = document.getElementById('tile-container'); - const tile = document.createElement('div'); - tile.className = `tile tile-${value}`; - if (isNew) tile.classList.add('tile-new'); - - tile.textContent = value; - tile.style.left = `${y * (100/4)}%`; - tile.style.top = `${x * (100/4)}%`; - tile.dataset.x = x; - tile.dataset.y = y; - tile.dataset.value = value; - - container.appendChild(tile); - - // 移除动画类 - setTimeout(() => { - tile.classList.remove('tile-new'); - }, 200); - } - - updateDisplay() { - // 清除所有方块 - const container = document.getElementById('tile-container'); - container.innerHTML = ''; - - // 重新创建所有方块 - for (let i = 0; i < this.size; i++) { - for (let j = 0; j < this.size; j++) { - if (this.grid[i][j] !== 0) { - this.createTileElement(i, j, this.grid[i][j]); - } - } - } - - // 更新分数 - document.getElementById('score').textContent = this.score; - document.getElementById('best-score').textContent = this.bestScore; - - // 更新统计数据显示 - if (window.gameStats) { - window.gameStats.updateDisplay(); - } - } - - move(direction) { - if (this.gameOver) return; - - this.moved = false; - const previousGrid = this.grid.map(row => [...row]); - - switch (direction) { - case 'up': - this.moveUp(); - break; - case 'down': - this.moveDown(); - break; - case 'left': - this.moveLeft(); - break; - case 'right': - this.moveRight(); - break; - } - - if (this.moved) { - this.stats.moves++; - this.addRandomTile(); - this.updateDisplay(); - - if (this.isGameWon() && !this.gameWon) { - this.gameWon = true; - this.showGameWon(); - } else if (this.isGameOver()) { - this.gameOver = true; - this.showGameOver(); - } - } - } - - moveLeft() { - for (let i = 0; i < this.size; i++) { - const row = this.grid[i].filter(val => val !== 0); - const merged = []; - - for (let j = 0; j < row.length - 1; j++) { - if (row[j] === row[j + 1] && !merged[j] && !merged[j + 1]) { - row[j] *= 2; - this.score += row[j]; - this.stats.mergeCount++; - this.stats.maxTile = Math.max(this.stats.maxTile, row[j]); - row[j + 1] = 0; - merged[j] = true; - } - } - - const newRow = row.filter(val => val !== 0); - while (newRow.length < this.size) { - newRow.push(0); - } - - for (let j = 0; j < this.size; j++) { - if (this.grid[i][j] !== newRow[j]) { - this.moved = true; - } - this.grid[i][j] = newRow[j]; - } - } - } - - moveRight() { - for (let i = 0; i < this.size; i++) { - const row = this.grid[i].filter(val => val !== 0); - const merged = []; - - for (let j = row.length - 1; j > 0; j--) { - if (row[j] === row[j - 1] && !merged[j] && !merged[j - 1]) { - row[j] *= 2; - this.score += row[j]; - this.stats.mergeCount++; - this.stats.maxTile = Math.max(this.stats.maxTile, row[j]); - row[j - 1] = 0; - merged[j] = true; - } - } - - const newRow = row.filter(val => val !== 0); - while (newRow.length < this.size) { - newRow.unshift(0); - } - - for (let j = 0; j < this.size; j++) { - if (this.grid[i][j] !== newRow[j]) { - this.moved = true; - } - this.grid[i][j] = newRow[j]; - } - } - } - - moveUp() { - for (let j = 0; j < this.size; j++) { - const column = []; - for (let i = 0; i < this.size; i++) { - if (this.grid[i][j] !== 0) { - column.push(this.grid[i][j]); - } - } - - const merged = []; - for (let i = 0; i < column.length - 1; i++) { - if (column[i] === column[i + 1] && !merged[i] && !merged[i + 1]) { - column[i] *= 2; - this.score += column[i]; - this.stats.mergeCount++; - this.stats.maxTile = Math.max(this.stats.maxTile, column[i]); - column[i + 1] = 0; - merged[i] = true; - } - } - - const newColumn = column.filter(val => val !== 0); - while (newColumn.length < this.size) { - newColumn.push(0); - } - - for (let i = 0; i < this.size; i++) { - if (this.grid[i][j] !== newColumn[i]) { - this.moved = true; - } - this.grid[i][j] = newColumn[i]; - } - } - } - - moveDown() { - for (let j = 0; j < this.size; j++) { - const column = []; - for (let i = 0; i < this.size; i++) { - if (this.grid[i][j] !== 0) { - column.push(this.grid[i][j]); - } - } - - const merged = []; - for (let i = column.length - 1; i > 0; i--) { - if (column[i] === column[i - 1] && !merged[i] && !merged[i - 1]) { - column[i] *= 2; - this.score += column[i]; - this.stats.mergeCount++; - this.stats.maxTile = Math.max(this.stats.maxTile, column[i]); - column[i - 1] = 0; - merged[i] = true; - } - } - - const newColumn = column.filter(val => val !== 0); - while (newColumn.length < this.size) { - newColumn.unshift(0); - } - - for (let i = 0; i < this.size; i++) { - if (this.grid[i][j] !== newColumn[i]) { - this.moved = true; - } - this.grid[i][j] = newColumn[i]; - } - } - } - - isGameWon() { - for (let i = 0; i < this.size; i++) { - for (let j = 0; j < this.size; j++) { - if (this.grid[i][j] === 2048) { - return true; - } - } - } - return false; - } - - isGameOver() { - // 检查是否有空格 - for (let i = 0; i < this.size; i++) { - for (let j = 0; j < this.size; j++) { - if (this.grid[i][j] === 0) { - return false; - } - } - } - - // 检查是否可以合并 - for (let i = 0; i < this.size; i++) { - for (let j = 0; j < this.size; j++) { - const current = this.grid[i][j]; - if ( - (i > 0 && this.grid[i - 1][j] === current) || - (i < this.size - 1 && this.grid[i + 1][j] === current) || - (j > 0 && this.grid[i][j - 1] === current) || - (j < this.size - 1 && this.grid[i][j + 1] === current) - ) { - return false; - } - } - } - - return true; - } - - showGameWon() { - const message = document.getElementById('game-message'); - message.className = 'game-message game-won'; - message.style.display = 'flex'; - message.querySelector('p').textContent = '你赢了!'; - } - - showGameOver() { - const message = document.getElementById('game-message'); - message.className = 'game-message game-over'; - message.style.display = 'flex'; - message.querySelector('p').textContent = '游戏结束!'; - - // 显示最终统计 - setTimeout(() => { - if (window.gameStats) { - window.gameStats.showFinalStats(); - } - }, 1000); - } - - restart() { - this.score = 0; - this.gameWon = false; - this.gameOver = false; - this.moved = false; - - // 重置统计数据 - this.stats = { - moves: 0, - startTime: null, - gameTime: 0, - maxTile: 2, - mergeCount: 0 - }; - - this.initializeGrid(); - this.addRandomTile(); - this.addRandomTile(); - this.updateDisplay(); - - // 隐藏游戏消息 - document.getElementById('game-message').style.display = 'none'; - - // 重新开始计时 - this.startTimer(); - } - - keepPlaying() { - document.getElementById('game-message').style.display = 'none'; - } - - startTimer() { - this.stats.startTime = Date.now(); - - if (this.timerInterval) { - clearInterval(this.timerInterval); - } - - this.timerInterval = setInterval(() => { - if (!this.gameOver && this.stats.startTime) { - this.stats.gameTime = Math.floor((Date.now() - this.stats.startTime) / 1000); - if (window.gameStats) { - window.gameStats.updateDisplay(); - } - } - }, 1000); - } - - bindEvents() { - // 重新开始按钮 - document.getElementById('restart-btn').addEventListener('click', () => { - this.restart(); - }); - - // 继续游戏按钮 - document.getElementById('keep-playing').addEventListener('click', () => { - this.keepPlaying(); - }); - - // 重试按钮 - document.getElementById('retry-btn').addEventListener('click', () => { - this.restart(); - }); - } - - updateBestScore() { - if (this.score > this.bestScore) { - this.bestScore = this.score; - localStorage.setItem('2048-best-score', this.bestScore.toString()); - } - } -} - -// 游戏实例 -let game; - -// 页面加载完成后初始化游戏 -document.addEventListener('DOMContentLoaded', () => { - game = new Game2048(); - - // 监听分数变化以更新最高分 - const originalUpdateDisplay = game.updateDisplay.bind(game); - game.updateDisplay = function() { - originalUpdateDisplay(); - this.updateBestScore(); - }; - - // 导出游戏实例供其他模块使用 - window.game2048 = game; -}); \ No newline at end of file diff --git a/frontend/smallgame/2048/index.html b/frontend/smallgame/2048/index.html deleted file mode 100755 index e3b1cc17..00000000 --- a/frontend/smallgame/2048/index.html +++ /dev/null @@ -1,165 +0,0 @@ - - - - - - 2048游戏 - - - -
      -
      -

      2048

      -
      -
      -
      分数
      -
      0
      -
      -
      -
      最高分
      -
      0
      -
      -
      -
      - -
      -

      - 合并相同数字,达到2048! -

      -
      新游戏
      -
      - -
      - - -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      - -
      - -
      -
      - -
      -

      游戏统计

      -
      -
      - 移动次数: - 0 -
      -
      - 游戏时间: - 00:00 -
      -
      - 最大数字: - 2 -
      -
      - 合并次数: - 0 -
      -
      -
      - -
      -

      操作说明:

      -

      手机: 滑动屏幕移动方块

      -

      电脑: 使用方向键 ↑↓←→ 或 WASD 键

      -
      -
      - - - - - - - - - \ No newline at end of file diff --git a/frontend/smallgame/2048/statistics.js b/frontend/smallgame/2048/statistics.js deleted file mode 100755 index f01543ed..00000000 --- a/frontend/smallgame/2048/statistics.js +++ /dev/null @@ -1,381 +0,0 @@ -// 游戏统计模块 -class GameStatistics { - constructor() { - this.achievements = { - firstWin: false, - speedRunner: false, // 5分钟内达到2048 - efficient: false, // 少于500步达到2048 - persistent: false, // 游戏时间超过30分钟 - merger: false, // 单局合并超过100次 - highScorer: false // 分数超过50000 - }; - - this.loadAchievements(); - this.initializeModal(); - } - - updateDisplay() { - if (!window.game2048) return; - - const game = window.game2048; - - // 更新实时统计显示 - document.getElementById('moves-count').textContent = game.stats.moves; - document.getElementById('game-time').textContent = this.formatTime(game.stats.gameTime); - document.getElementById('max-tile').textContent = game.stats.maxTile; - document.getElementById('merge-count').textContent = game.stats.mergeCount; - } - - formatTime(seconds) { - const minutes = Math.floor(seconds / 60); - const remainingSeconds = seconds % 60; - return `${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`; - } - - showFinalStats() { - if (!window.game2048) return; - - const game = window.game2048; - const modal = document.getElementById('stats-modal'); - - // 更新最终统计数据 - document.getElementById('final-score').textContent = game.score; - document.getElementById('final-moves').textContent = game.stats.moves; - document.getElementById('final-time').textContent = this.formatTime(game.stats.gameTime); - document.getElementById('final-max-tile').textContent = game.stats.maxTile; - document.getElementById('final-merges').textContent = game.stats.mergeCount; - - // 计算平均每步得分 - const avgScore = game.stats.moves > 0 ? Math.round(game.score / game.stats.moves) : 0; - document.getElementById('avg-score').textContent = avgScore; - - // 检查成就 - this.checkAchievements(game); - - // 显示模态框 - modal.style.display = 'block'; - - // 添加动画效果 - setTimeout(() => { - modal.querySelector('.modal-content').style.transform = 'scale(1)'; - }, 10); - } - - checkAchievements(game) { - let newAchievements = []; - - // 首次胜利 - if (game.gameWon && !this.achievements.firstWin) { - this.achievements.firstWin = true; - newAchievements.push('🏆 首次胜利!达到了2048!'); - } - - // 速度跑者 - 5分钟内达到2048 - if (game.gameWon && game.stats.gameTime <= 300 && !this.achievements.speedRunner) { - this.achievements.speedRunner = true; - newAchievements.push('⚡ 速度跑者!5分钟内达到2048!'); - } - - // 高效玩家 - 少于500步达到2048 - if (game.gameWon && game.stats.moves < 500 && !this.achievements.efficient) { - this.achievements.efficient = true; - newAchievements.push('🎯 高效玩家!少于500步达到2048!'); - } - - // 坚持不懈 - 游戏时间超过30分钟 - if (game.stats.gameTime >= 1800 && !this.achievements.persistent) { - this.achievements.persistent = true; - newAchievements.push('⏰ 坚持不懈!游戏时间超过30分钟!'); - } - - // 合并大师 - 单局合并超过100次 - if (game.stats.mergeCount >= 100 && !this.achievements.merger) { - this.achievements.merger = true; - newAchievements.push('🔥 合并大师!单局合并超过100次!'); - } - - // 高分玩家 - 分数超过50000 - if (game.score >= 50000 && !this.achievements.highScorer) { - this.achievements.highScorer = true; - newAchievements.push('💎 高分玩家!分数超过50000!'); - } - - // 保存成就 - if (newAchievements.length > 0) { - this.saveAchievements(); - this.showAchievementNotifications(newAchievements); - } - } - - showAchievementNotifications(achievements) { - // 在成就区域显示新获得的成就 - const achievementSection = document.querySelector('.achievement-section'); - - achievements.forEach((achievement, index) => { - setTimeout(() => { - const notification = document.createElement('div'); - notification.className = 'achievement-notification'; - notification.innerHTML = ` -
      - ${achievement} -
      - `; - - achievementSection.appendChild(notification); - - // 添加样式 - const popup = notification.querySelector('.achievement-popup'); - popup.style.cssText = ` - background: linear-gradient(45deg, #ff6b6b, #feca57); - color: white; - padding: 10px 15px; - border-radius: 20px; - margin: 5px 0; - font-weight: bold; - text-align: center; - animation: achievementSlide 0.5s ease-out; - box-shadow: 0 4px 12px rgba(0,0,0,0.2); - `; - - // 添加动画样式 - if (!document.getElementById('achievement-styles')) { - const style = document.createElement('style'); - style.id = 'achievement-styles'; - style.textContent = ` - @keyframes achievementSlide { - from { - opacity: 0; - transform: translateX(-100%); - } - to { - opacity: 1; - transform: translateX(0); - } - } - `; - document.head.appendChild(style); - } - - // 3秒后移除通知 - setTimeout(() => { - if (notification.parentNode) { - notification.remove(); - } - }, 3000); - }, index * 500); - }); - } - - saveAchievements() { - localStorage.setItem('2048-achievements', JSON.stringify(this.achievements)); - } - - loadAchievements() { - const saved = localStorage.getItem('2048-achievements'); - if (saved) { - this.achievements = { ...this.achievements, ...JSON.parse(saved) }; - } - } - - initializeModal() { - const modal = document.getElementById('stats-modal'); - const closeBtn = document.getElementById('close-modal'); - const newGameBtn = document.getElementById('new-game-btn'); - const shareBtn = document.getElementById('share-btn'); - - // 关闭模态框 - closeBtn.addEventListener('click', () => { - modal.style.display = 'none'; - }); - - // 点击模态框外部关闭 - modal.addEventListener('click', (e) => { - if (e.target === modal) { - modal.style.display = 'none'; - } - }); - - // 新游戏按钮 - newGameBtn.addEventListener('click', () => { - modal.style.display = 'none'; - if (window.game2048) { - window.game2048.restart(); - } - }); - - // 分享按钮 - shareBtn.addEventListener('click', () => { - this.shareScore(); - }); - - // ESC键关闭模态框 - document.addEventListener('keydown', (e) => { - if (e.key === 'Escape' && modal.style.display === 'block') { - modal.style.display = 'none'; - } - }); - } - - shareScore() { - if (!window.game2048) return; - - const game = window.game2048; - const shareText = `我在2048游戏中获得了${game.score}分!\n` + - `最大数字: ${game.stats.maxTile}\n` + - `移动次数: ${game.stats.moves}\n` + - `游戏时间: ${this.formatTime(game.stats.gameTime)}\n` + - `来挑战一下吧!`; - - // 尝试使用Web Share API - if (navigator.share) { - navigator.share({ - title: '2048游戏成绩', - text: shareText, - url: window.location.href - }).catch(err => { - console.log('分享失败:', err); - this.fallbackShare(shareText); - }); - } else { - this.fallbackShare(shareText); - } - } - - fallbackShare(text) { - // 复制到剪贴板 - if (navigator.clipboard) { - navigator.clipboard.writeText(text).then(() => { - this.showToast('成绩已复制到剪贴板!'); - }).catch(() => { - this.showShareModal(text); - }); - } else { - this.showShareModal(text); - } - } - - showShareModal(text) { - // 创建分享文本显示框 - const shareModal = document.createElement('div'); - shareModal.innerHTML = ` -
      -

      分享你的成绩

      - -
      - - -
      -
      - `; - - document.body.appendChild(shareModal); - } - - showToast(message) { - const toast = document.createElement('div'); - toast.textContent = message; - toast.style.cssText = ` - position: fixed; - top: 20px; - left: 50%; - transform: translateX(-50%); - background: rgba(0, 0, 0, 0.8); - color: white; - padding: 12px 24px; - border-radius: 25px; - z-index: 10000; - font-weight: bold; - animation: toastSlide 0.3s ease-out; - `; - - document.body.appendChild(toast); - - setTimeout(() => { - toast.remove(); - }, 3000); - } - - // 获取游戏统计摘要 - getStatsSummary() { - if (!window.game2048) return null; - - const game = window.game2048; - return { - score: game.score, - bestScore: game.bestScore, - moves: game.stats.moves, - gameTime: game.stats.gameTime, - maxTile: game.stats.maxTile, - mergeCount: game.stats.mergeCount, - achievements: this.achievements - }; - } - - // 重置所有统计数据 - resetAllStats() { - this.achievements = { - firstWin: false, - speedRunner: false, - efficient: false, - persistent: false, - merger: false, - highScorer: false - }; - - localStorage.removeItem('2048-achievements'); - localStorage.removeItem('2048-best-score'); - - this.showToast('所有统计数据已重置!'); - } -} - -// 创建全局统计实例 -window.gameStats = new GameStatistics(); - -// 页面加载完成后初始化 -document.addEventListener('DOMContentLoaded', () => { - // 确保统计模块正确初始化 - if (!window.gameStats) { - window.gameStats = new GameStatistics(); - } -}); \ No newline at end of file diff --git a/frontend/smallgame/2048/styles.css b/frontend/smallgame/2048/styles.css deleted file mode 100755 index 0e28186f..00000000 --- a/frontend/smallgame/2048/styles.css +++ /dev/null @@ -1,611 +0,0 @@ -/* 基础样式重置 */ -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -body { - font-family: 'Arial', 'Microsoft YaHei', sans-serif; - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - color: #776e65; - font-size: 18px; - margin: 0; - padding: 0; - min-height: 100vh; - overflow-x: hidden; -} - -.container { - max-width: 500px; - margin: 0 auto; - padding: 20px; - position: relative; -} - -/* 头部样式 */ -.header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 20px; - flex-wrap: wrap; -} - -.title { - font-size: 48px; - font-weight: bold; - color: #ffffff; - text-shadow: 2px 2px 4px rgba(0,0,0,0.3); - margin: 0; -} - -.score-container { - display: flex; - gap: 10px; -} - -.score-box { - background: rgba(255, 255, 255, 0.9); - padding: 10px 15px; - border-radius: 8px; - text-align: center; - min-width: 80px; - box-shadow: 0 2px 8px rgba(0,0,0,0.1); -} - -.score-label { - font-size: 12px; - color: #776e65; - text-transform: uppercase; - font-weight: bold; -} - -.score { - font-size: 20px; - font-weight: bold; - color: #ffffff; - background: linear-gradient(45deg, #ff6b6b, #ee5a24); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; -} - -/* 游戏介绍区域 */ -.game-intro { - background: rgba(255, 255, 255, 0.9); - padding: 15px; - border-radius: 12px; - margin-bottom: 20px; - text-align: center; - box-shadow: 0 4px 12px rgba(0,0,0,0.1); -} - -.game-explanation { - margin-bottom: 15px; - font-size: 16px; - line-height: 1.5; -} - -.restart-button { - background: linear-gradient(45deg, #4ecdc4, #44a08d); - color: white; - padding: 12px 24px; - border-radius: 25px; - cursor: pointer; - font-weight: bold; - transition: all 0.3s ease; - display: inline-block; - box-shadow: 0 4px 12px rgba(0,0,0,0.2); -} - -.restart-button:hover { - transform: translateY(-2px); - box-shadow: 0 6px 16px rgba(0,0,0,0.3); -} - -/* 游戏容器 */ -.game-container { - position: relative; - background: rgba(255, 255, 255, 0.9); - border-radius: 12px; - padding: 15px; - margin-bottom: 20px; - box-shadow: 0 4px 12px rgba(0,0,0,0.1); -} - -/* 网格样式 */ -.grid-container { - position: relative; - z-index: 1; -} - -.grid-row { - display: flex; - margin-bottom: 8px; -} - -.grid-row:last-child { - margin-bottom: 0; -} - -.grid-cell { - width: calc(25% - 6px); - height: 80px; - background: rgba(238, 228, 218, 0.35); - border-radius: 8px; - margin-right: 8px; - position: relative; -} - -.grid-cell:last-child { - margin-right: 0; -} - -/* 数字方块容器 */ -.tile-container { - position: absolute; - top: 15px; - left: 15px; - right: 15px; - bottom: 15px; - z-index: 2; -} - -/* 数字方块样式 */ -.tile { - position: absolute; - width: calc(25% - 6px); - height: 80px; - border-radius: 8px; - font-weight: bold; - display: flex; - justify-content: center; - align-items: center; - font-size: 32px; - transition: all 0.15s ease-in-out; - box-shadow: 0 2px 8px rgba(0,0,0,0.1); -} - -/* 不同数字的颜色 */ -.tile-2 { background: #eee4da; color: #776e65; } -.tile-4 { background: #ede0c8; color: #776e65; } -.tile-8 { background: #f2b179; color: #f9f6f2; } -.tile-16 { background: #f59563; color: #f9f6f2; } -.tile-32 { background: #f67c5f; color: #f9f6f2; } -.tile-64 { background: #f65e3b; color: #f9f6f2; } -.tile-128 { background: #edcf72; color: #f9f6f2; font-size: 28px; } -.tile-256 { background: #edcc61; color: #f9f6f2; font-size: 28px; } -.tile-512 { background: #edc850; color: #f9f6f2; font-size: 28px; } -.tile-1024 { background: #edc53f; color: #f9f6f2; font-size: 24px; } -.tile-2048 { background: #edc22e; color: #f9f6f2; font-size: 24px; box-shadow: 0 0 20px rgba(237, 194, 46, 0.5); } -.tile-super { background: #3c3a32; color: #f9f6f2; font-size: 20px; } - -/* 动画效果 */ -.tile-new { - animation: appear 0.2s ease-in-out; -} - -.tile-merged { - animation: pop 0.2s ease-in-out; -} - -@keyframes appear { - 0% { - opacity: 0; - transform: scale(0); - } - 100% { - opacity: 1; - transform: scale(1); - } -} - -@keyframes pop { - 0% { - transform: scale(1); - } - 50% { - transform: scale(1.2); - } - 100% { - transform: scale(1); - } -} - -/* 游戏消息 */ -.game-message { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: rgba(255, 255, 255, 0.95); - z-index: 100; - text-align: center; - display: none; - flex-direction: column; - justify-content: center; - align-items: center; - border-radius: 12px; -} - -.game-message.game-won { - background: rgba(237, 194, 46, 0.9); - color: #f9f6f2; -} - -.game-message.game-over { - background: rgba(238, 228, 218, 0.9); - color: #776e65; -} - -.game-message p { - font-size: 36px; - font-weight: bold; - margin-bottom: 20px; -} - -.lower { - display: flex; - gap: 15px; -} - -.keep-playing-button, -.retry-button { - background: #8f7a66; - color: #f9f6f2; - padding: 12px 24px; - border-radius: 8px; - text-decoration: none; - font-weight: bold; - cursor: pointer; - transition: all 0.3s ease; -} - -.keep-playing-button:hover, -.retry-button:hover { - background: #9f8a76; - transform: translateY(-2px); -} - -/* 游戏统计 */ -.game-stats { - background: rgba(255, 255, 255, 0.9); - padding: 15px; - border-radius: 12px; - margin-bottom: 20px; - box-shadow: 0 4px 12px rgba(0,0,0,0.1); -} - -.game-stats h3 { - text-align: center; - margin-bottom: 15px; - color: #776e65; - font-size: 20px; -} - -.stats-grid { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 10px; -} - -.stat-item { - display: flex; - justify-content: space-between; - align-items: center; - padding: 8px 12px; - background: rgba(238, 228, 218, 0.3); - border-radius: 6px; -} - -.stat-label { - font-size: 14px; - color: #776e65; -} - -.stat-value { - font-weight: bold; - color: #f67c5f; - font-size: 16px; -} - -/* 操作提示 */ -.controls-hint { - background: rgba(255, 255, 255, 0.9); - padding: 15px; - border-radius: 12px; - text-align: center; - font-size: 14px; - line-height: 1.6; - box-shadow: 0 4px 12px rgba(0,0,0,0.1); -} - -.controls-hint p { - margin-bottom: 5px; -} - -.controls-hint p:last-child { - margin-bottom: 0; -} - -/* 模态框样式 */ -.modal { - display: none; - position: fixed; - z-index: 1000; - left: 0; - top: 0; - width: 100%; - height: 100%; - background-color: rgba(0, 0, 0, 0.5); - backdrop-filter: blur(5px); -} - -.modal-content { - background-color: #fefefe; - margin: 5% auto; - border-radius: 15px; - width: 90%; - max-width: 500px; - max-height: 90vh; - overflow-y: auto; - box-shadow: 0 10px 30px rgba(0,0,0,0.3); - animation: modalSlideIn 0.3s ease-out; -} - -@keyframes modalSlideIn { - from { - opacity: 0; - transform: translateY(-50px); - } - to { - opacity: 1; - transform: translateY(0); - } -} - -.modal-header { - padding: 20px; - border-bottom: 1px solid #eee; - display: flex; - justify-content: space-between; - align-items: center; - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - color: white; - border-radius: 15px 15px 0 0; -} - -.modal-header h2 { - margin: 0; - font-size: 24px; -} - -.close { - color: white; - font-size: 28px; - font-weight: bold; - cursor: pointer; - transition: color 0.3s ease; -} - -.close:hover { - color: #ddd; -} - -.modal-body { - padding: 20px; -} - -.final-score { - text-align: center; - margin-bottom: 25px; - padding: 20px; - background: linear-gradient(135deg, #ff9a9e 0%, #fecfef 100%); - border-radius: 10px; - color: white; -} - -.final-score h3 { - margin: 0; - font-size: 28px; - text-shadow: 1px 1px 2px rgba(0,0,0,0.2); -} - -.achievement-section h4 { - text-align: center; - margin-bottom: 20px; - color: #776e65; - font-size: 20px; -} - -.achievement-grid { - display: grid; - grid-template-columns: 1fr; - gap: 15px; - margin-bottom: 25px; -} - -.achievement-item { - display: flex; - align-items: center; - padding: 15px; - background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%); - border-radius: 10px; - box-shadow: 0 2px 8px rgba(0,0,0,0.1); - transition: transform 0.3s ease; -} - -.achievement-item:hover { - transform: translateY(-2px); -} - -.achievement-icon { - font-size: 32px; - margin-right: 15px; -} - -.achievement-info { - flex: 1; -} - -.achievement-title { - font-size: 14px; - color: #666; - margin-bottom: 5px; -} - -.achievement-value { - font-size: 20px; - font-weight: bold; - color: #333; -} - -.modal-actions { - display: flex; - gap: 15px; - justify-content: center; -} - -.btn { - padding: 12px 24px; - border: none; - border-radius: 25px; - font-size: 16px; - font-weight: bold; - cursor: pointer; - transition: all 0.3s ease; - text-decoration: none; - display: inline-block; -} - -.btn-primary { - background: linear-gradient(45deg, #4ecdc4, #44a08d); - color: white; -} - -.btn-secondary { - background: linear-gradient(45deg, #ff9a9e, #fecfef); - color: white; -} - -.btn:hover { - transform: translateY(-2px); - box-shadow: 0 6px 16px rgba(0,0,0,0.2); -} - -/* 手机端优化 */ -@media (max-width: 480px) { - .container { - padding: 15px; - } - - .title { - font-size: 36px; - } - - .header { - flex-direction: column; - gap: 15px; - text-align: center; - } - - .score-container { - justify-content: center; - } - - .grid-cell, - .tile { - height: 70px; - font-size: 28px; - } - - .tile-128, - .tile-256, - .tile-512 { - font-size: 24px; - } - - .tile-1024, - .tile-2048 { - font-size: 20px; - } - - .tile-super { - font-size: 16px; - } - - .game-message p { - font-size: 28px; - } - - .modal-content { - margin: 10% auto; - width: 95%; - } - - .achievement-grid { - grid-template-columns: 1fr; - } - - .modal-actions { - flex-direction: column; - } -} - -/* 超小屏幕优化 */ -@media (max-width: 360px) { - .grid-cell, - .tile { - height: 60px; - font-size: 24px; - } - - .tile-128, - .tile-256, - .tile-512 { - font-size: 20px; - } - - .tile-1024, - .tile-2048 { - font-size: 18px; - } - - .tile-super { - font-size: 14px; - } -} - -/* 电脑端优化 */ -@media (min-width: 768px) { - .container { - padding: 30px; - } - - .grid-cell, - .tile { - height: 90px; - font-size: 36px; - } - - .achievement-grid { - grid-template-columns: 1fr 1fr; - } - - .modal-actions { - flex-direction: row; - } -} - -/* 触摸优化 */ -@media (hover: none) and (pointer: coarse) { - .restart-button, - .keep-playing-button, - .retry-button, - .btn { - min-height: 44px; - min-width: 44px; - } -} \ No newline at end of file diff --git a/frontend/smallgame/俄罗斯方块/game-controls.js b/frontend/smallgame/俄罗斯方块/game-controls.js deleted file mode 100755 index 99a5a22b..00000000 --- a/frontend/smallgame/俄罗斯方块/game-controls.js +++ /dev/null @@ -1,279 +0,0 @@ -// 游戏控制模块 -class GameControls { - constructor(game) { - this.game = game; - this.keys = {}; - this.keyRepeatDelay = 150; - this.keyRepeatInterval = 50; - this.keyTimers = {}; - - this.init(); - } - - init() { - this.setupKeyboardControls(); - this.setupTouchControls(); - this.setupButtonControls(); - } - - setupKeyboardControls() { - document.addEventListener('keydown', (e) => { - this.handleKeyDown(e); - }); - - document.addEventListener('keyup', (e) => { - this.handleKeyUp(e); - }); - } - - handleKeyDown(e) { - const key = e.key; - - // 防止重复触发 - if (this.keys[key]) return; - this.keys[key] = true; - - switch(key) { - case 'ArrowLeft': - e.preventDefault(); - this.game.moveLeft(); - this.startKeyRepeat('ArrowLeft', () => this.game.moveLeft()); - break; - - case 'ArrowRight': - e.preventDefault(); - this.game.moveRight(); - this.startKeyRepeat('ArrowRight', () => this.game.moveRight()); - break; - - case 'ArrowDown': - e.preventDefault(); - this.game.moveDown(); - this.startKeyRepeat('ArrowDown', () => this.game.moveDown()); - break; - - case 'ArrowUp': - e.preventDefault(); - this.game.rotatePiece(); - break; - - case ' ': - e.preventDefault(); - if (this.game.gameRunning) { - this.game.pause(); - } - break; - - case 'Enter': - e.preventDefault(); - if (!this.game.gameRunning) { - this.game.start(); - } - break; - - case 'r': - case 'R': - if (e.ctrlKey) { - e.preventDefault(); - this.game.restart(); - } - break; - - case 'Escape': - e.preventDefault(); - if (this.game.gameRunning) { - this.game.pause(); - } - break; - } - } - - handleKeyUp(e) { - const key = e.key; - this.keys[key] = false; - this.stopKeyRepeat(key); - } - - startKeyRepeat(key, action) { - this.stopKeyRepeat(key); - - this.keyTimers[key] = setTimeout(() => { - const intervalId = setInterval(() => { - if (this.keys[key]) { - action(); - } else { - clearInterval(intervalId); - } - }, this.keyRepeatInterval); - - this.keyTimers[key] = intervalId; - }, this.keyRepeatDelay); - } - - stopKeyRepeat(key) { - if (this.keyTimers[key]) { - clearTimeout(this.keyTimers[key]); - clearInterval(this.keyTimers[key]); - delete this.keyTimers[key]; - } - } - - setupTouchControls() { - // 移动端触摸控制 - const leftBtn = document.getElementById('leftBtn'); - const rightBtn = document.getElementById('rightBtn'); - const downBtn = document.getElementById('downBtn'); - const rotateBtn = document.getElementById('rotateBtn'); - const dropBtn = document.getElementById('dropBtn'); - const pauseBtn = document.getElementById('pauseBtn'); - - // 左移 - this.addTouchEvents(leftBtn, () => this.game.moveLeft()); - - // 右移 - this.addTouchEvents(rightBtn, () => this.game.moveRight()); - - // 下移 - this.addTouchEvents(downBtn, () => this.game.moveDown()); - - // 旋转 - rotateBtn.addEventListener('touchstart', (e) => { - e.preventDefault(); - this.game.rotatePiece(); - }); - - rotateBtn.addEventListener('click', (e) => { - e.preventDefault(); - this.game.rotatePiece(); - }); - - // 硬降 - dropBtn.addEventListener('touchstart', (e) => { - e.preventDefault(); - this.game.hardDrop(); - }); - - dropBtn.addEventListener('click', (e) => { - e.preventDefault(); - this.game.hardDrop(); - }); - - // 暂停 - pauseBtn.addEventListener('touchstart', (e) => { - e.preventDefault(); - this.game.pause(); - }); - - pauseBtn.addEventListener('click', (e) => { - e.preventDefault(); - this.game.pause(); - }); - } - - addTouchEvents(element, action) { - let touchInterval; - let touchTimeout; - - const startAction = (e) => { - e.preventDefault(); - action(); - - touchTimeout = setTimeout(() => { - touchInterval = setInterval(action, this.keyRepeatInterval); - }, this.keyRepeatDelay); - }; - - const stopAction = (e) => { - e.preventDefault(); - if (touchTimeout) { - clearTimeout(touchTimeout); - touchTimeout = null; - } - if (touchInterval) { - clearInterval(touchInterval); - touchInterval = null; - } - }; - - element.addEventListener('touchstart', startAction); - element.addEventListener('touchend', stopAction); - element.addEventListener('touchcancel', stopAction); - element.addEventListener('mousedown', startAction); - element.addEventListener('mouseup', stopAction); - element.addEventListener('mouseleave', stopAction); - } - - setupButtonControls() { - const startBtn = document.getElementById('startBtn'); - const restartBtn = document.getElementById('restartBtn'); - - startBtn.addEventListener('click', () => { - this.game.start(); - }); - - restartBtn.addEventListener('click', () => { - this.game.restart(); - }); - } - - // 游戏手势支持 - setupSwipeControls() { - let startX = 0; - let startY = 0; - let threshold = 50; - - this.game.canvas.addEventListener('touchstart', (e) => { - e.preventDefault(); - const touch = e.touches[0]; - startX = touch.clientX; - startY = touch.clientY; - }); - - this.game.canvas.addEventListener('touchmove', (e) => { - e.preventDefault(); - }); - - this.game.canvas.addEventListener('touchend', (e) => { - e.preventDefault(); - const touch = e.changedTouches[0]; - const deltaX = touch.clientX - startX; - const deltaY = touch.clientY - startY; - - if (Math.abs(deltaX) > Math.abs(deltaY)) { - // 水平滑动 - if (Math.abs(deltaX) > threshold) { - if (deltaX > 0) { - this.game.moveRight(); - } else { - this.game.moveLeft(); - } - } - } else { - // 垂直滑动 - if (Math.abs(deltaY) > threshold) { - if (deltaY > 0) { - this.game.moveDown(); - } else { - this.game.rotatePiece(); - } - } - } - }); - - // 双击旋转 - let lastTap = 0; - this.game.canvas.addEventListener('touchend', (e) => { - const currentTime = new Date().getTime(); - const tapLength = currentTime - lastTap; - - if (tapLength < 500 && tapLength > 0) { - e.preventDefault(); - this.game.rotatePiece(); - } - lastTap = currentTime; - }); - } -} - -// 初始化控制系统 -const gameControls = new GameControls(game); diff --git a/frontend/smallgame/俄罗斯方块/game-stats.js b/frontend/smallgame/俄罗斯方块/game-stats.js deleted file mode 100755 index 87d9ffd0..00000000 --- a/frontend/smallgame/俄罗斯方块/game-stats.js +++ /dev/null @@ -1,338 +0,0 @@ -// 游戏统计和成就系统 -class GameStats { - constructor() { - this.achievements = [ - { - id: 'first_game', - name: '初次体验', - description: '完成第一次游戏', - condition: (stats) => true - }, - { - id: 'score_1000', - name: '小试牛刀', - description: '单局得分达到1000分', - condition: (stats) => stats.score >= 1000 - }, - { - id: 'score_5000', - name: '游戏达人', - description: '单局得分达到5000分', - condition: (stats) => stats.score >= 5000 - }, - { - id: 'score_10000', - name: '方块大师', - description: '单局得分达到10000分', - condition: (stats) => stats.score >= 10000 - }, - { - id: 'level_5', - name: '步步高升', - description: '达到第5级', - condition: (stats) => stats.level >= 5 - }, - { - id: 'level_10', - name: '速度之王', - description: '达到第10级', - condition: (stats) => stats.level >= 10 - }, - { - id: 'lines_50', - name: '消除专家', - description: '累计消除50行', - condition: (stats) => stats.lines >= 50 - }, - { - id: 'lines_100', - name: '清理大师', - description: '累计消除100行', - condition: (stats) => stats.lines >= 100 - }, - { - id: 'tetris', - name: 'Tetris!', - description: '一次消除4行', - condition: (stats) => stats.maxCombo >= 4 - }, - { - id: 'time_10min', - name: '持久战士', - description: '单局游戏时间超过10分钟', - condition: (stats) => stats.playTime >= 600000 - }, - { - id: 'efficiency', - name: '效率专家', - description: '平均每分钟得分超过500', - condition: (stats) => stats.avgScore >= 500 - } - ]; - - this.init(); - } - - init() { - this.setupEventListeners(); - } - - setupEventListeners() { - const playAgainBtn = document.getElementById('playAgainBtn'); - playAgainBtn.addEventListener('click', () => { - this.hideStats(); - game.restart(); - }); - } - - showStats(gameData) { - const playTimeMinutes = gameData.playTime / 60000; - const avgScore = playTimeMinutes > 0 ? Math.round(gameData.score / playTimeMinutes) : 0; - - const stats = { - ...gameData, - avgScore: avgScore - }; - - // 更新统计显示 - document.getElementById('finalScore').textContent = stats.score.toLocaleString(); - document.getElementById('finalLevel').textContent = stats.level; - document.getElementById('finalLines').textContent = stats.lines; - document.getElementById('playTime').textContent = this.formatTime(stats.playTime); - document.getElementById('maxCombo').textContent = stats.maxCombo; - document.getElementById('avgScore').textContent = stats.avgScore; - - // 检查成就 - const achievement = this.checkAchievements(stats); - this.displayAchievement(achievement); - - // 显示统计界面 - document.getElementById('gameStats').style.display = 'flex'; - document.getElementById('gameStats').classList.add('fade-in'); - } - - hideStats() { - document.getElementById('gameStats').style.display = 'none'; - document.getElementById('gameStats').classList.remove('fade-in'); - } - - formatTime(milliseconds) { - const seconds = Math.floor(milliseconds / 1000); - const minutes = Math.floor(seconds / 60); - const remainingSeconds = seconds % 60; - - return `${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`; - } - - checkAchievements(stats) { - // 获取已获得的成就 - const earnedAchievements = this.getEarnedAchievements(); - - // 检查新成就 - for (let achievement of this.achievements) { - if (!earnedAchievements.includes(achievement.id) && - achievement.condition(stats)) { - - // 保存新成就 - this.saveAchievement(achievement.id); - return achievement; - } - } - - return null; - } - - displayAchievement(achievement) { - const achievementEl = document.getElementById('achievement'); - - if (achievement) { - achievementEl.innerHTML = ` - 🏆 成就解锁!
      - ${achievement.name}
      - ${achievement.description} - `; - achievementEl.classList.add('pulse'); - } else { - // 显示随机鼓励话语 - const encouragements = [ - '继续努力,你会变得更强!', - '每一次游戏都是进步的机会!', - '方块世界需要你的智慧!', - '熟能生巧,加油!', - '下一局一定会更好!', - '坚持就是胜利!', - '你的反应速度在提升!', - '策略思维正在增强!' - ]; - - const randomEncouragement = encouragements[Math.floor(Math.random() * encouragements.length)]; - achievementEl.innerHTML = `💪 ${randomEncouragement}`; - achievementEl.classList.remove('pulse'); - } - } - - getEarnedAchievements() { - const saved = localStorage.getItem('tetris_achievements'); - return saved ? JSON.parse(saved) : []; - } - - saveAchievement(achievementId) { - const earned = this.getEarnedAchievements(); - if (!earned.includes(achievementId)) { - earned.push(achievementId); - localStorage.setItem('tetris_achievements', JSON.stringify(earned)); - } - } - - // 获取历史最佳记录 - getBestStats() { - const saved = localStorage.getItem('tetris_best_stats'); - return saved ? JSON.parse(saved) : { - score: 0, - level: 0, - lines: 0, - maxCombo: 0 - }; - } - - // 保存最佳记录 - saveBestStats(stats) { - const best = this.getBestStats(); - let updated = false; - - if (stats.score > best.score) { - best.score = stats.score; - updated = true; - } - - if (stats.level > best.level) { - best.level = stats.level; - updated = true; - } - - if (stats.lines > best.lines) { - best.lines = stats.lines; - updated = true; - } - - if (stats.maxCombo > best.maxCombo) { - best.maxCombo = stats.maxCombo; - updated = true; - } - - if (updated) { - localStorage.setItem('tetris_best_stats', JSON.stringify(best)); - } - - return updated; - } - - // 显示排行榜 - showLeaderboard() { - const best = this.getBestStats(); - const earned = this.getEarnedAchievements(); - - console.log('最佳记录:', best); - console.log('已获得成就:', earned.length + '/' + this.achievements.length); - } -} - -// 高级特效系统 -class GameEffects { - constructor(game) { - this.game = game; - this.particles = []; - this.effects = []; - - this.init(); - } - - init() { - // 创建特效canvas - this.effectsCanvas = document.createElement('canvas'); - this.effectsCanvas.width = this.game.canvas.width; - this.effectsCanvas.height = this.game.canvas.height; - this.effectsCanvas.style.position = 'absolute'; - this.effectsCanvas.style.top = '0'; - this.effectsCanvas.style.left = '0'; - this.effectsCanvas.style.pointerEvents = 'none'; - this.effectsCanvas.style.zIndex = '10'; - - this.effectsCtx = this.effectsCanvas.getContext('2d'); - - // 将特效canvas添加到游戏板容器中 - this.game.canvas.parentElement.style.position = 'relative'; - this.game.canvas.parentElement.appendChild(this.effectsCanvas); - } - - // 行消除特效 - lineCleared(row) { - for (let i = 0; i < 20; i++) { - this.particles.push({ - x: Math.random() * this.game.canvas.width, - y: row * this.game.CELL_SIZE + this.game.CELL_SIZE / 2, - vx: (Math.random() - 0.5) * 10, - vy: (Math.random() - 0.5) * 10, - life: 1, - decay: 0.02, - color: `hsl(${Math.random() * 360}, 100%, 50%)` - }); - } - } - - // 方块锁定特效 - pieceLocked(piece) { - const centerX = (piece.x + piece.matrix[0].length / 2) * this.game.CELL_SIZE; - const centerY = (piece.y + piece.matrix.length / 2) * this.game.CELL_SIZE; - - for (let i = 0; i < 10; i++) { - this.particles.push({ - x: centerX, - y: centerY, - vx: (Math.random() - 0.5) * 8, - vy: (Math.random() - 0.5) * 8, - life: 0.8, - decay: 0.03, - color: piece.color - }); - } - } - - // 更新特效 - update() { - // 更新粒子 - for (let i = this.particles.length - 1; i >= 0; i--) { - const particle = this.particles[i]; - - particle.x += particle.vx; - particle.y += particle.vy; - particle.life -= particle.decay; - - if (particle.life <= 0) { - this.particles.splice(i, 1); - } - } - } - - // 绘制特效 - draw() { - this.effectsCtx.clearRect(0, 0, this.effectsCanvas.width, this.effectsCanvas.height); - - // 绘制粒子 - for (let particle of this.particles) { - this.effectsCtx.save(); - this.effectsCtx.globalAlpha = particle.life; - this.effectsCtx.fillStyle = particle.color; - this.effectsCtx.beginPath(); - this.effectsCtx.arc(particle.x, particle.y, 3, 0, Math.PI * 2); - this.effectsCtx.fill(); - this.effectsCtx.restore(); - } - } -} - -// 创建统计系统实例 -const gameStats = new GameStats(); - -// 在适当的地方创建特效系统 -// const gameEffects = new GameEffects(game); diff --git a/frontend/smallgame/俄罗斯方块/index.html b/frontend/smallgame/俄罗斯方块/index.html deleted file mode 100755 index c7cf159d..00000000 --- a/frontend/smallgame/俄罗斯方块/index.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - 俄罗斯方块 - - - -
      -
      -

      俄罗斯方块

      -
      -
      - 分数: - 0 -
      -
      - 等级: - 1 -
      -
      - 消除行数: - 0 -
      -
      -
      - -
      -
      - -
      -
      -

      游戏暂停

      -

      按空格键继续游戏

      - - -
      -
      -
      - -
      -
      -

      下一个

      - -
      - -
      -

      操作说明

      -
      - ←→ - 移动 -
      -
      - - 快速下降 -
      -
      - - 旋转 -
      -
      - 空格 - 暂停/继续 -
      -
      -
      -
      - - -
      -
      - - - -
      -
      - - - -
      -
      -
      - - -
      -
      -

      游戏结束

      -
      -
      - 最终分数 - 0 -
      -
      - 达到等级 - 1 -
      -
      - 消除行数 - 0 -
      -
      - 游戏时长 - 00:00 -
      -
      - 单次消除最大行数 - 0 -
      -
      - 平均每分钟分数 - 0 -
      -
      -
      - -
      -
      - - - - - - diff --git a/frontend/smallgame/俄罗斯方块/styles.css b/frontend/smallgame/俄罗斯方块/styles.css deleted file mode 100755 index 58d03476..00000000 --- a/frontend/smallgame/俄罗斯方块/styles.css +++ /dev/null @@ -1,459 +0,0 @@ -/* 基础样式重置 */ -* { - margin: 0; - padding: 0; - box-sizing: border-box; - -webkit-tap-highlight-color: transparent; -} - -body { - font-family: 'Arial', sans-serif; - background: linear-gradient(135deg, #1e3c72, #2a5298); - color: white; - height: 100vh; - overflow: hidden; - user-select: none; -} - -/* 游戏容器 */ -.game-container { - height: 100vh; - display: flex; - flex-direction: column; - max-width: 800px; - margin: 0 auto; - padding: 10px; -} - -/* 游戏头部 */ -.game-header { - text-align: center; - margin-bottom: 15px; -} - -.game-header h1 { - font-size: 2rem; - margin-bottom: 10px; - text-shadow: 2px 2px 4px rgba(0,0,0,0.5); -} - -.score-board { - display: flex; - justify-content: center; - gap: 20px; - flex-wrap: wrap; -} - -.score-item { - background: rgba(255,255,255,0.1); - padding: 8px 15px; - border-radius: 20px; - backdrop-filter: blur(10px); - border: 1px solid rgba(255,255,255,0.2); -} - -.score-item .label { - font-size: 0.9rem; - opacity: 0.8; -} - -.score-item span:last-child { - font-weight: bold; - margin-left: 5px; -} - -/* 游戏主体 */ -.game-main { - display: flex; - flex: 1; - gap: 20px; - justify-content: center; - align-items: flex-start; -} - -.game-board { - position: relative; - border-radius: 10px; - overflow: hidden; - box-shadow: 0 10px 30px rgba(0,0,0,0.3); -} - -#gameCanvas { - display: block; - background: #1a1a1a; - border: 2px solid #333; -} - -/* 游戏覆盖层 */ -.game-overlay { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: rgba(0,0,0,0.8); - display: flex; - align-items: center; - justify-content: center; - backdrop-filter: blur(5px); -} - -.overlay-content { - text-align: center; - background: rgba(255,255,255,0.1); - padding: 30px; - border-radius: 15px; - border: 1px solid rgba(255,255,255,0.2); -} - -.overlay-content h2 { - margin-bottom: 15px; - font-size: 1.8rem; -} - -.overlay-content p { - margin-bottom: 20px; - opacity: 0.8; -} - -/* 游戏按钮 */ -.game-btn { - background: linear-gradient(45deg, #667eea, #764ba2); - border: none; - color: white; - padding: 12px 24px; - border-radius: 25px; - cursor: pointer; - font-size: 1rem; - margin: 5px; - transition: all 0.3s ease; - box-shadow: 0 4px 15px rgba(0,0,0,0.2); -} - -.game-btn:hover { - transform: translateY(-2px); - box-shadow: 0 6px 20px rgba(0,0,0,0.3); -} - -.game-btn:active { - transform: translateY(0); -} - -/* 侧边栏 */ -.game-sidebar { - display: flex; - flex-direction: column; - gap: 20px; - min-width: 150px; -} - -.next-piece { - background: rgba(255,255,255,0.1); - padding: 15px; - border-radius: 10px; - border: 1px solid rgba(255,255,255,0.2); - text-align: center; -} - -.next-piece h3 { - margin-bottom: 10px; - font-size: 1.1rem; -} - -#nextCanvas { - background: #1a1a1a; - border: 1px solid #333; - border-radius: 5px; -} - -.controls-info { - background: rgba(255,255,255,0.1); - padding: 15px; - border-radius: 10px; - border: 1px solid rgba(255,255,255,0.2); -} - -.controls-info h3 { - margin-bottom: 15px; - font-size: 1.1rem; - text-align: center; -} - -.control-item { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 8px; - padding: 5px 0; -} - -.control-item .key { - background: rgba(255,255,255,0.2); - padding: 4px 8px; - border-radius: 4px; - font-family: monospace; - font-size: 0.9rem; -} - -.control-item .desc { - font-size: 0.9rem; - opacity: 0.8; -} - -/* 手机端控制 */ -.mobile-controls { - display: none; - position: absolute; - top: 50%; - transform: translateY(-50%); - width: 100%; - pointer-events: none; - z-index: 20; -} - -.mobile-controls-left { - position: absolute; - left: 10px; - display: flex; - flex-direction: column; - gap: 15px; - pointer-events: auto; -} - -.mobile-controls-right { - position: absolute; - right: 10px; - display: flex; - flex-direction: column; - gap: 15px; - pointer-events: auto; -} - -.control-btn { - width: 55px; - height: 55px; - border: none; - border-radius: 50%; - background: linear-gradient(45deg, #667eea, #764ba2); - color: white; - font-size: 1.4rem; - cursor: pointer; - transition: all 0.2s ease; - box-shadow: 0 4px 15px rgba(0,0,0,0.3); - user-select: none; - backdrop-filter: blur(10px); - border: 2px solid rgba(255,255,255,0.2); -} - -.control-btn:active { - transform: scale(0.9); - box-shadow: 0 2px 8px rgba(0,0,0,0.4); -} - -/* 游戏统计界面 */ -.game-stats { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: rgba(0,0,0,0.9); - display: none; - align-items: center; - justify-content: center; - z-index: 1000; - backdrop-filter: blur(10px); -} - -.stats-content { - background: linear-gradient(135deg, #667eea, #764ba2); - padding: 30px; - border-radius: 20px; - text-align: center; - max-width: 90%; - width: 400px; - box-shadow: 0 20px 40px rgba(0,0,0,0.3); -} - -.stats-content h2 { - margin-bottom: 25px; - font-size: 2rem; - text-shadow: 2px 2px 4px rgba(0,0,0,0.3); -} - -.stats-grid { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 15px; - margin-bottom: 25px; -} - -.stat-item { - background: rgba(255,255,255,0.1); - padding: 15px; - border-radius: 10px; - border: 1px solid rgba(255,255,255,0.2); -} - -.stat-label { - display: block; - font-size: 0.9rem; - opacity: 0.8; - margin-bottom: 5px; -} - -.stat-value { - display: block; - font-size: 1.4rem; - font-weight: bold; -} - -.achievement { - background: linear-gradient(45deg, #f093fb, #f5576c); - padding: 15px; - border-radius: 10px; - margin-bottom: 25px; - font-weight: bold; - min-height: 50px; - display: flex; - align-items: center; - justify-content: center; -} - -/* 响应式设计 */ -@media (max-width: 768px) { - .game-container { - padding: 5px; - position: relative; - } - - .game-header h1 { - font-size: 1.5rem; - } - - .score-board { - gap: 10px; - } - - .score-item { - padding: 6px 12px; - font-size: 0.9rem; - } - - .game-main { - flex-direction: column; - align-items: center; - gap: 15px; - position: relative; - } - - .game-board { - position: relative; - z-index: 10; - } - - .game-sidebar { - flex-direction: row; - justify-content: center; - min-width: unset; - width: 100%; - } - - .next-piece, - .controls-info { - flex: 1; - max-width: 200px; - } - - .mobile-controls { - display: block; - } - - #gameCanvas { - width: 250px; - height: 500px; - } - - .stats-grid { - grid-template-columns: 1fr; - gap: 10px; - } - - .stats-content { - padding: 20px; - width: 95%; - } -} - -@media (max-width: 480px) { - .game-header h1 { - font-size: 1.3rem; - } - - .score-board { - gap: 8px; - } - - .score-item { - padding: 4px 8px; - font-size: 0.8rem; - } - - #gameCanvas { - width: 200px; - height: 400px; - } - - .control-btn { - width: 45px; - height: 45px; - font-size: 1.2rem; - } - - .mobile-controls-left, - .mobile-controls-right { - gap: 10px; - } - - .mobile-controls-left { - left: 5px; - } - - .mobile-controls-right { - right: 5px; - } - - .game-sidebar { - flex-direction: column; - gap: 10px; - } - - .next-piece, - .controls-info { - max-width: unset; - } -} - -/* 隐藏类 */ -.hidden { - display: none !important; -} - -/* 动画效果 */ -@keyframes fadeIn { - from { opacity: 0; transform: translateY(20px); } - to { opacity: 1; transform: translateY(0); } -} - -.fade-in { - animation: fadeIn 0.5s ease-out; -} - -@keyframes pulse { - 0%, 100% { transform: scale(1); } - 50% { transform: scale(1.05); } -} - -.pulse { - animation: pulse 2s infinite; -} diff --git a/frontend/smallgame/俄罗斯方块/tetris.js b/frontend/smallgame/俄罗斯方块/tetris.js deleted file mode 100755 index 1b49cf31..00000000 --- a/frontend/smallgame/俄罗斯方块/tetris.js +++ /dev/null @@ -1,521 +0,0 @@ -// 俄罗斯方块主游戏逻辑 -class TetrisGame { - constructor() { - this.canvas = document.getElementById('gameCanvas'); - this.ctx = this.canvas.getContext('2d'); - this.nextCanvas = document.getElementById('nextCanvas'); - this.nextCtx = this.nextCanvas.getContext('2d'); - - // 游戏配置 - this.BOARD_WIDTH = 10; - this.BOARD_HEIGHT = 20; - this.CELL_SIZE = 30; - - // 游戏状态 - this.board = []; - this.currentPiece = null; - this.nextPiece = null; - this.score = 0; - this.level = 1; - this.lines = 0; - this.dropTime = 0; - this.dropInterval = 1000; // 初始下降间隔(毫秒) - this.gameRunning = false; - this.gamePaused = false; - this.lastTime = 0; - - // 统计数据 - this.gameStartTime = 0; - this.maxCombo = 0; - this.currentCombo = 0; - - // 方块类型定义 - this.pieces = { - I: { - color: '#00f5ff', - matrix: [ - [0, 0, 0, 0], - [1, 1, 1, 1], - [0, 0, 0, 0], - [0, 0, 0, 0] - ] - }, - O: { - color: '#ffff00', - matrix: [ - [1, 1], - [1, 1] - ] - }, - T: { - color: '#800080', - matrix: [ - [0, 1, 0], - [1, 1, 1], - [0, 0, 0] - ] - }, - S: { - color: '#00ff00', - matrix: [ - [0, 1, 1], - [1, 1, 0], - [0, 0, 0] - ] - }, - Z: { - color: '#ff0000', - matrix: [ - [1, 1, 0], - [0, 1, 1], - [0, 0, 0] - ] - }, - J: { - color: '#0000ff', - matrix: [ - [1, 0, 0], - [1, 1, 1], - [0, 0, 0] - ] - }, - L: { - color: '#ffa500', - matrix: [ - [0, 0, 1], - [1, 1, 1], - [0, 0, 0] - ] - } - }; - - this.pieceTypes = Object.keys(this.pieces); - - this.init(); - } - - init() { - this.initBoard(); - this.nextPiece = this.createPiece(); - this.spawnPiece(); - this.updateDisplay(); - this.showOverlay('游戏准备', '点击开始游戏按钮开始'); - } - - initBoard() { - this.board = []; - for (let row = 0; row < this.BOARD_HEIGHT; row++) { - this.board[row] = []; - for (let col = 0; col < this.BOARD_WIDTH; col++) { - this.board[row][col] = 0; - } - } - } - - createPiece() { - const type = this.pieceTypes[Math.floor(Math.random() * this.pieceTypes.length)]; - const piece = this.pieces[type]; - return { - type: type, - color: piece.color, - matrix: this.copyMatrix(piece.matrix), - x: Math.floor(this.BOARD_WIDTH / 2) - Math.floor(piece.matrix[0].length / 2), - y: 0 - }; - } - - copyMatrix(matrix) { - return matrix.map(row => [...row]); - } - - spawnPiece() { - this.currentPiece = this.nextPiece; - this.nextPiece = this.createPiece(); - this.currentPiece.x = Math.floor(this.BOARD_WIDTH / 2) - Math.floor(this.currentPiece.matrix[0].length / 2); - this.currentPiece.y = 0; - - // 检查游戏结束 - if (this.collision(this.currentPiece)) { - this.gameOver(); - return false; - } - - this.drawNextPiece(); - return true; - } - - collision(piece, dx = 0, dy = 0) { - const matrix = piece.matrix; - const x = piece.x + dx; - const y = piece.y + dy; - - for (let row = 0; row < matrix.length; row++) { - for (let col = 0; col < matrix[row].length; col++) { - if (matrix[row][col] !== 0) { - const newX = x + col; - const newY = y + row; - - if (newX < 0 || newX >= this.BOARD_WIDTH || - newY >= this.BOARD_HEIGHT || - (newY >= 0 && this.board[newY][newX] !== 0)) { - return true; - } - } - } - } - return false; - } - - rotate(piece) { - const matrix = piece.matrix; - const N = matrix.length; - const rotated = []; - - // 创建旋转后的矩阵 - for (let i = 0; i < N; i++) { - rotated[i] = []; - for (let j = 0; j < N; j++) { - rotated[i][j] = matrix[N - 1 - j][i]; - } - } - - return rotated; - } - - hardDrop() { - while (!this.collision(this.currentPiece, 0, 1)) { - this.currentPiece.y++; - this.score += 2; // 硬降给额外分数 - } - this.lockPiece(); - } - - lockPiece() { - const matrix = this.currentPiece.matrix; - const x = this.currentPiece.x; - const y = this.currentPiece.y; - - // 将方块锁定到游戏板上 - for (let row = 0; row < matrix.length; row++) { - for (let col = 0; col < matrix[row].length; col++) { - if (matrix[row][col] !== 0) { - if (y + row >= 0) { - this.board[y + row][x + col] = this.currentPiece.color; - } - } - } - } - - // 检查并清除完整的行 - const linesCleared = this.clearLines(); - if (linesCleared > 0) { - this.lines += linesCleared; - this.currentCombo = linesCleared; - this.maxCombo = Math.max(this.maxCombo, this.currentCombo); - - // 计算分数 (基于消除行数和等级) - const lineScores = [0, 40, 100, 300, 1200]; - this.score += lineScores[linesCleared] * this.level; - - // 升级逻辑 - this.level = Math.floor(this.lines / 10) + 1; - this.dropInterval = Math.max(50, 1000 - (this.level - 1) * 50); - } else { - this.currentCombo = 0; - } - - // 生成下一个方块 - this.spawnPiece(); - this.updateDisplay(); - } - - clearLines() { - let linesCleared = 0; - - for (let row = this.BOARD_HEIGHT - 1; row >= 0; row--) { - if (this.board[row].every(cell => cell !== 0)) { - // 移除完整的行 - this.board.splice(row, 1); - // 在顶部添加新的空行 - this.board.unshift(new Array(this.BOARD_WIDTH).fill(0)); - linesCleared++; - row++; // 重新检查当前行 - } - } - - return linesCleared; - } - - update(deltaTime) { - if (!this.gameRunning || this.gamePaused) return; - - this.dropTime += deltaTime; - - if (this.dropTime >= this.dropInterval) { - if (!this.collision(this.currentPiece, 0, 1)) { - this.currentPiece.y++; - // 自然下降不加分 - } else { - this.lockPiece(); - } - this.dropTime = 0; - } - } - - draw() { - this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); - - // 绘制游戏板 - this.drawBoard(); - - // 绘制当前方块 - if (this.currentPiece) { - this.drawPiece(this.currentPiece, this.ctx); - } - - // 绘制网格 - this.drawGrid(); - } - - drawBoard() { - for (let row = 0; row < this.BOARD_HEIGHT; row++) { - for (let col = 0; col < this.BOARD_WIDTH; col++) { - if (this.board[row][col] !== 0) { - this.ctx.fillStyle = this.board[row][col]; - this.ctx.fillRect( - col * this.CELL_SIZE, - row * this.CELL_SIZE, - this.CELL_SIZE, - this.CELL_SIZE - ); - this.ctx.strokeStyle = '#333'; - this.ctx.lineWidth = 1; - this.ctx.strokeRect( - col * this.CELL_SIZE, - row * this.CELL_SIZE, - this.CELL_SIZE, - this.CELL_SIZE - ); - } - } - } - } - - drawPiece(piece, context) { - context.fillStyle = piece.color; - const matrix = piece.matrix; - - for (let row = 0; row < matrix.length; row++) { - for (let col = 0; col < matrix[row].length; col++) { - if (matrix[row][col] !== 0) { - context.fillRect( - (piece.x + col) * this.CELL_SIZE, - (piece.y + row) * this.CELL_SIZE, - this.CELL_SIZE, - this.CELL_SIZE - ); - context.strokeStyle = '#333'; - context.lineWidth = 1; - context.strokeRect( - (piece.x + col) * this.CELL_SIZE, - (piece.y + row) * this.CELL_SIZE, - this.CELL_SIZE, - this.CELL_SIZE - ); - } - } - } - } - - drawGrid() { - this.ctx.strokeStyle = 'rgba(255, 255, 255, 0.1)'; - this.ctx.lineWidth = 1; - - // 垂直线 - for (let col = 0; col <= this.BOARD_WIDTH; col++) { - this.ctx.beginPath(); - this.ctx.moveTo(col * this.CELL_SIZE, 0); - this.ctx.lineTo(col * this.CELL_SIZE, this.canvas.height); - this.ctx.stroke(); - } - - // 水平线 - for (let row = 0; row <= this.BOARD_HEIGHT; row++) { - this.ctx.beginPath(); - this.ctx.moveTo(0, row * this.CELL_SIZE); - this.ctx.lineTo(this.canvas.width, row * this.CELL_SIZE); - this.ctx.stroke(); - } - } - - drawNextPiece() { - this.nextCtx.clearRect(0, 0, this.nextCanvas.width, this.nextCanvas.height); - - if (this.nextPiece) { - const size = 20; - const matrix = this.nextPiece.matrix; - const offsetX = (this.nextCanvas.width - matrix[0].length * size) / 2; - const offsetY = (this.nextCanvas.height - matrix.length * size) / 2; - - this.nextCtx.fillStyle = this.nextPiece.color; - - for (let row = 0; row < matrix.length; row++) { - for (let col = 0; col < matrix[row].length; col++) { - if (matrix[row][col] !== 0) { - this.nextCtx.fillRect( - offsetX + col * size, - offsetY + row * size, - size, - size - ); - this.nextCtx.strokeStyle = '#333'; - this.nextCtx.lineWidth = 1; - this.nextCtx.strokeRect( - offsetX + col * size, - offsetY + row * size, - size, - size - ); - } - } - } - } - } - - updateDisplay() { - document.getElementById('score').textContent = this.score; - document.getElementById('level').textContent = this.level; - document.getElementById('lines').textContent = this.lines; - } - - showOverlay(title, message) { - document.getElementById('overlayTitle').textContent = title; - document.getElementById('overlayMessage').textContent = message; - document.getElementById('gameOverlay').style.display = 'flex'; - } - - hideOverlay() { - document.getElementById('gameOverlay').style.display = 'none'; - } - - start() { - this.gameRunning = true; - this.gamePaused = false; - this.gameStartTime = Date.now(); - this.hideOverlay(); - this.gameLoop(); - } - - pause() { - if (!this.gameRunning) return; - - this.gamePaused = !this.gamePaused; - - if (this.gamePaused) { - this.showOverlay('游戏暂停', '按空格键继续游戏'); - } else { - this.hideOverlay(); - this.gameLoop(); - } - } - - restart() { - this.gameRunning = false; - this.gamePaused = false; - this.score = 0; - this.level = 1; - this.lines = 0; - this.dropTime = 0; - this.dropInterval = 1000; - this.maxCombo = 0; - this.currentCombo = 0; - - this.init(); - this.start(); - } - - gameOver() { - this.gameRunning = false; - this.gamePaused = false; - - // 显示游戏统计 - gameStats.showStats({ - score: this.score, - level: this.level, - lines: this.lines, - playTime: Date.now() - this.gameStartTime, - maxCombo: this.maxCombo - }); - } - - gameLoop(currentTime = 0) { - if (!this.gameRunning || this.gamePaused) return; - - const deltaTime = currentTime - this.lastTime; - this.lastTime = currentTime; - - this.update(deltaTime); - this.draw(); - - requestAnimationFrame((time) => this.gameLoop(time)); - } - - // 移动方法 - moveLeft() { - if (this.gameRunning && !this.gamePaused && this.currentPiece) { - if (!this.collision(this.currentPiece, -1, 0)) { - this.currentPiece.x--; - } - } - } - - moveRight() { - if (this.gameRunning && !this.gamePaused && this.currentPiece) { - if (!this.collision(this.currentPiece, 1, 0)) { - this.currentPiece.x++; - } - } - } - - moveDown() { - if (this.gameRunning && !this.gamePaused && this.currentPiece) { - if (!this.collision(this.currentPiece, 0, 1)) { - this.currentPiece.y++; - this.score += 1; // 只有主动按下键才给软降分数 - } - } - } - - rotatePiece() { - if (this.gameRunning && !this.gamePaused && this.currentPiece) { - const rotated = this.rotate(this.currentPiece); - const originalMatrix = this.currentPiece.matrix; - this.currentPiece.matrix = rotated; - - // 检查旋转后是否会碰撞 - if (this.collision(this.currentPiece)) { - // 尝试wall kick - const kicks = [ - [-1, 0], [1, 0], [0, -1], [-2, 0], [2, 0] - ]; - - let canRotate = false; - for (let kick of kicks) { - if (!this.collision(this.currentPiece, kick[0], kick[1])) { - this.currentPiece.x += kick[0]; - this.currentPiece.y += kick[1]; - canRotate = true; - break; - } - } - - if (!canRotate) { - this.currentPiece.matrix = originalMatrix; - } - } - } - } -} - -// 创建游戏实例 -const game = new TetrisGame(); diff --git a/frontend/smallgame/别踩白方块/MUSIC.mp3 b/frontend/smallgame/别踩白方块/MUSIC.mp3 deleted file mode 100755 index eedeb54c..00000000 Binary files a/frontend/smallgame/别踩白方块/MUSIC.mp3 and /dev/null differ diff --git a/frontend/smallgame/别踩白方块/game.js b/frontend/smallgame/别踩白方块/game.js deleted file mode 100755 index b8e1adff..00000000 --- a/frontend/smallgame/别踩白方块/game.js +++ /dev/null @@ -1,339 +0,0 @@ -var c = document.getElementById("piano"); -var context = c.getContext("2d"); -var b = document.getElementById("background"); -var context_back = b.getContext("2d"); -var a = document.getElementById("score_bar"); -var context_score = a.getContext("2d"); - - -var numOfTiles = 5; -var myScore = 0; -var eachState = [false,false,false,false,false]; -var myTiles = []; - -var intervalTmp; -var geneTmp; -var gameSpeed = 1; // 游戏速度倍数,初始为1倍 -var baseInterval = 5; // 基础更新间隔(毫秒) -var baseGenerateInterval = 600; // 基础生成间隔(毫秒) - -paintWindow(); -paintScoreBar(); - -// 添加全局鼠标和触摸事件监听 -c.addEventListener('click', function(e) { - handleClick(e); -}); - -c.addEventListener('touchstart', function(e) { - e.preventDefault(); - handleTouch(e); -}); - -document.getElementById('start_btn').addEventListener('click',function(e){ - var content = document.getElementById('start_btn'); - if(content.innerHTML == "开始游戏" || content.innerHTML == "继续游戏"){ - startGame(); - } - else{ - pauseGame(); - } -}); - -// 重新开始按钮事件 -document.getElementById('restart-btn').addEventListener('click', function(){ - restartGame(); -}); - -function startGame(){ - var content = document.getElementById('start_btn'); - updateGameSpeed(); - document.getElementById('music').play(); - content.innerHTML = "暂停游戏"; - content.className = "game-btn pause-btn"; -} - -// 更新游戏速度 -function updateGameSpeed() { - // 清除现有定时器 - if (intervalTmp) clearInterval(intervalTmp); - if (geneTmp) clearInterval(geneTmp); - - // 保持正常1倍速度,不加速 - gameSpeed = 1; - - // 设置新的定时器,优化性能 - intervalTmp = setInterval(upDate, Math.max(baseInterval / gameSpeed, 3)); - geneTmp = setInterval(geneBlock, Math.max(baseGenerateInterval / gameSpeed, 200)); -} - -function pauseGame(){ - var content = document.getElementById('start_btn'); - document.getElementById('music').pause(); - window.clearInterval(intervalTmp); - window.clearInterval(geneTmp); - content.innerHTML = "继续游戏"; - content.className = "game-btn start-btn"; -} - -function gameOver(){ - document.getElementById('music').pause(); - window.clearInterval(intervalTmp); - window.clearInterval(geneTmp); - - // 显示最终得分和达到的最高速度 - document.getElementById('final-score-value').innerHTML = myScore; - document.getElementById('final-speed-value').innerHTML = gameSpeed.toFixed(1); - - // 显示游戏结束弹窗 - document.getElementById('game-over-modal').style.display = 'flex'; -} - -function restartGame(){ - // 重置游戏状态 - myScore = 0; - gameSpeed = 1; // 重置游戏速度 - eachState = [false,false,false,false,false]; - myTiles = []; - - // 清空画布 - context.clearRect(0,0,300,600); - context_back.clearRect(0,0,300,600); - context_score.clearRect(0,0,300,60); - - // 重新绘制背景 - paintWindow(); - paintScoreBar(); - - // 隐藏弹窗 - document.getElementById('game-over-modal').style.display = 'none'; - - // 重置按钮状态 - var content = document.getElementById('start_btn'); - content.innerHTML = "开始游戏"; - content.className = "game-btn start-btn"; -} -function paintScoreBar(){ - // 清空画布 - context_score.clearRect(0,0,300,60); - - // 绘制黑色背景 - context_score.fillStyle = "#333"; - context_score.fillRect(0,0,300,60); - - // 更新HTML显示 - document.getElementById('score-value').textContent = myScore; - document.getElementById('speed-value').textContent = gameSpeed.toFixed(1); -} -function geneBlock(){ - var myRand = Math.floor(Math.random()*numOfTiles); - var i; - var flag = true; - for( i = 0; i < numOfTiles; ++i){ - if(!eachState[i]){ - flag = false; - } - } - if(flag)return;//if mytiles array didn't have false element, then return - - while(eachState[myRand]) - myRand = Math.floor(Math.random()*numOfTiles); - myTiles[myRand] = new Block(myRand); - -} -function paintWindow(){ - // 清空背景 - context_back.clearRect(0,0,300,600); - - // 绘制白色背景 - context_back.fillStyle = "white"; - context_back.fillRect(0,0,300,600); - - // 绘制分隔线 - context_back.strokeStyle = "#ddd"; - context_back.lineWidth = 2; - - // 垂直分隔线 - context_back.beginPath(); - context_back.moveTo(75,0); - context_back.lineTo(75,600); - context_back.stroke(); - - context_back.beginPath(); - context_back.moveTo(150,0); - context_back.lineTo(150,600); - context_back.stroke(); - - context_back.beginPath(); - context_back.moveTo(225,0); - context_back.lineTo(225,600); - context_back.stroke(); - - // 可点击区域警戒线 - context_back.strokeStyle = "#ff4444"; - context_back.lineWidth = 3; - context_back.beginPath(); - context_back.moveTo(0,250); - context_back.lineTo(300,250); - context_back.stroke(); - - // 底部失败线 - context_back.strokeStyle = "#ff4444"; - context_back.lineWidth = 3; - context_back.beginPath(); - context_back.moveTo(0,470); - context_back.lineTo(300,470); - context_back.stroke(); -} -function Block(index){ - if(!eachState[index]) - eachState[index] = true; - - this.index = index; - this.appearPos = Math.floor(Math.random()*4); - - this.width = 75; - this.height = 120; - this.color = "black"; - switch(this.appearPos){ - case 0: - this.x = 0; - this.y = -120; - break; - case 1: - this.x = 75; - this.y = -120; - break; - case 2: - this.x = 150; - this.y = -120; - break; - case 3: - this.x = 225; - this.y = -120; - break; - } - context.fillStyle = this.color; - context.fillRect(this.x,this.y,this.width,this.height); - this.live = true; - - window.addEventListener('keydown',function(e){ - myTiles[index].keyCode = e.keyCode; - }); - window.addEventListener('keyup',function(e){ - myTiles[index].keyCode = false; - }); -} -function move(index){ - if(myTiles[index].live){ - myTiles[index].y += Math.ceil(gameSpeed); - // 绘制逻辑已移到upDate函数中,避免重复绘制 - } -} -function afterRight(index){ - myScore++; - // 清除方块(在upDate中统一处理绘制) - myTiles[index].live = false; - eachState[index] = false; - - // 立即更新得分显示 - paintScoreBar(); - - // 每次得分都更新游戏速度,实现平滑渐进加速 - updateGameSpeed(); -} -// 处理鼠标点击事件 -function handleClick(e) { - var rect = c.getBoundingClientRect(); - var x = e.clientX - rect.left; - var y = e.clientY - rect.top; - - checkHit(x, y); -} - -// 处理触摸事件 -function handleTouch(e) { - var rect = c.getBoundingClientRect(); - var touch = e.touches[0]; - var x = touch.clientX - rect.left; - var y = touch.clientY - rect.top; - - checkHit(x, y); -} - -// 检查点击/触摸是否命中方块 -function checkHit(x, y) { - // 检查是否点击到黑色方块 - for (var i = 0; i < numOfTiles; i++) { - if (eachState[i] && myTiles[i].live) { - // 检查点击位置是否在方块范围内 - if (x >= myTiles[i].x && x <= myTiles[i].x + 75 && - y >= myTiles[i].y && y <= myTiles[i].y + 120) { - // 检查方块是否在可点击区域(提高到130像素以上) - if (myTiles[i].y + 120 > 130) { - afterRight(i); - return true; - } - } - } - } - - // 如果没有点击到任何黑色方块,且点击位置在游戏区域内,则游戏结束 - if (y > 130 && y < 600) { - gameOver(); - return false; - } - - return false; -} - -function upDate(){//check keyCode whether correct - var i; - - // 清空整个游戏区域,避免重叠 - context.clearRect(0, 0, 300, 600); - - // 移动并重绘所有活跃的方块 - for(i = 0; i < numOfTiles; ++i){ - if(eachState[i]){ - myTiles[i].y += Math.ceil(gameSpeed); // 使用整数移动,避免模糊 - context.fillStyle = "black"; - context.fillRect(myTiles[i].x, myTiles[i].y, 75, 120); - } - } - for(i = 0; i < numOfTiles; ++i){ - if( eachState[i] ){ - if(myTiles[i].y < 470 && myTiles[i].y >350){ - switch(myTiles[i].keyCode){ - case 65: //A - if(myTiles[i].x == 0) - afterRight(i); - break; - case 83: //S - if(myTiles[i].x == 75) - afterRight(i); - break; - case 68: //D - if(myTiles[i].x == 150) - afterRight(i); - break; - case 70: //F - if(myTiles[i].x == 225) - afterRight(i); - break; - } - } - if(myTiles[i].y > 470){ - // 方块到达底部,游戏结束 - myTiles[i].live = false; - eachState[i] = false; - gameOver(); - return; // 立即退出,避免继续处理 - } - } - else{//not alive - - } - } -} - \ No newline at end of file diff --git a/frontend/smallgame/别踩白方块/index.html b/frontend/smallgame/别踩白方块/index.html deleted file mode 100755 index b86e9b55..00000000 --- a/frontend/smallgame/别踩白方块/index.html +++ /dev/null @@ -1,251 +0,0 @@ - - - - - 别踩白方块 - - - -
      -

      别踩白方块

      - -
      - -
      - 得分: 0 - 速度: 1.0x -
      -
      - -
      - - -
      - -
      - -
      -
      电脑端:使用 A S D F 键
      -
      手机端:直接点击黑色方块
      -
      -
      -
      - - -
      - -
      - - - - - \ No newline at end of file diff --git a/frontend/smallgame/生成要求.txt b/frontend/smallgame/生成要求.txt deleted file mode 100755 index a1bf9601..00000000 --- a/frontend/smallgame/生成要求.txt +++ /dev/null @@ -1,6 +0,0 @@ -1.把js,css,html分开储存,每个功能单独分成每个模块,避免单个文件过大问题 -2.网页适配手机端和电脑端,优先优化手机竖屏游玩体验,所有游戏都是手机竖屏游戏 -3.游戏都是无尽模式,玩到后期越来越困难,游戏玩法尽可能丰富多样 -4.电脑端可以有键盘快捷键操作 -5.最后结束游戏要统计显示玩家获得的最终游戏数据,给玩家成就感 -6.尽量不要在游戏网页中出现网页滚动条,会影响玩家的游玩体验 \ No newline at end of file diff --git a/frontend/src/contexts/UserContext.js b/frontend/src/contexts/UserContext.js index b2ac651b..6ae79f46 100755 --- a/frontend/src/contexts/UserContext.js +++ b/frontend/src/contexts/UserContext.js @@ -13,26 +13,52 @@ export const useUser = () => { }; export const UserProvider = ({ children }) => { - const [user, setUser] = useState(null); + const [user, setUser] = useState(() => { + // 从localStorage恢复用户信息 + try { + const savedUser = localStorage.getItem('user'); + return savedUser ? JSON.parse(savedUser) : null; + } catch { + return null; + } + }); const [isLoading, setIsLoading] = useState(true); - const [isLoggedIn, setIsLoggedIn] = useState(false); + const [isLoggedIn, setIsLoggedIn] = useState(() => { + // 从localStorage恢复登录状态和token + return localStorage.getItem('token') !== null; + }); // 检查登录状态 const checkLoginStatus = async () => { try { + const token = localStorage.getItem('token'); + if (!token) { + setUser(null); + setIsLoggedIn(false); + return; + } + const response = await authAPI.checkLogin(); if (response.data.success && response.data.logged_in) { const userData = response.data.user; setUser(userData); setIsLoggedIn(true); + // 保存到localStorage + localStorage.setItem('user', JSON.stringify(userData)); } else { setUser(null); setIsLoggedIn(false); + // 清除localStorage + localStorage.removeItem('user'); + localStorage.removeItem('token'); } } catch (error) { console.error('检查登录状态失败:', error); setUser(null); setIsLoggedIn(false); + // 清除localStorage + localStorage.removeItem('user'); + localStorage.removeItem('token'); } finally { setIsLoading(false); } @@ -44,8 +70,12 @@ export const UserProvider = ({ children }) => { const response = await authAPI.login(loginData); if (response.data.success) { const userData = response.data.user; + const token = response.data.token; setUser(userData); setIsLoggedIn(true); + // 保存到localStorage + localStorage.setItem('user', JSON.stringify(userData)); + localStorage.setItem('token', token); toast.success('登录成功!'); return { success: true }; } else { @@ -66,12 +96,18 @@ export const UserProvider = ({ children }) => { await authAPI.logout(); setUser(null); setIsLoggedIn(false); + // 清除localStorage + localStorage.removeItem('user'); + localStorage.removeItem('token'); toast.success('已成功登出'); } catch (error) { console.error('登出失败:', error); // 即使登出请求失败,也清除本地状态 setUser(null); setIsLoggedIn(false); + // 清除localStorage + localStorage.removeItem('user'); + localStorage.removeItem('isLoggedIn'); toast.error('登出失败'); } }; diff --git a/frontend/src/utils/api.js b/frontend/src/utils/api.js index 0f780772..9631853f 100755 --- a/frontend/src/utils/api.js +++ b/frontend/src/utils/api.js @@ -18,7 +18,11 @@ console.log('🌐 最终使用的 API Base URL:', process.env.REACT_APP_API_URL // 请求拦截器 api.interceptors.request.use( (config) => { - // 可以在这里添加token等认证信息 + // 添加JWT token到请求头 + const token = localStorage.getItem('token'); + if (token) { + config.headers.Authorization = `Bearer ${token}`; + } return config; }, (error) => { @@ -36,7 +40,9 @@ api.interceptors.response.use( const message = error.response?.data?.message || '网络错误,请稍后重试'; if (error.response?.status === 401) { - // 未授权,跳转到登录页 + // 未授权,清除token并跳转到登录页 + localStorage.removeItem('token'); + localStorage.removeItem('user'); window.location.href = '/login'; }