From 6889ca37e5927e306f2e82fb7f262fa9eb66a960 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=A0=91=E8=90=8C=E8=8A=BD?= <3205788256@qq.com>
Date: Mon, 8 Sep 2025 22:08:09 +0800
Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=9B=B4=E5=A4=9A=E7=9A=84AP?=
=?UTF-8?q?I=E6=8E=A5=E5=8F=A3=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../实时天气[目前有问题]/background.css | 202 ++++
.../实用功能/实时天气[目前有问题]/index.html | 143 +++
.../实用功能/实时天气[目前有问题]/script.js | 354 +++++++
.../实用功能/实时天气[目前有问题]/styles.css | 442 +++++++++
.../实时天气[目前有问题]/返回接口.json | 68 ++
.../实用功能/密码强度检测/css/style.css | 878 ++++++++++++++++++
.../60sapi/实用功能/密码强度检测/index.html | 218 +++++
.../60sapi/实用功能/密码强度检测/js/script.js | 516 ++++++++++
.../实用功能/密码强度检测/返回接口.json | 37 +
frontend/60sapi/实用功能/生成要求模板.txt | 8 -
.../实用功能/身体健康分析/background.css | 243 +++++
.../60sapi/实用功能/身体健康分析/index.html | 115 +++
.../60sapi/实用功能/身体健康分析/script.js | 515 ++++++++++
.../60sapi/实用功能/身体健康分析/styles.css | 697 ++++++++++++++
.../实用功能/身体健康分析/返回接口.json | 93 ++
.../60sapi/实用功能/配色方案/background.css | 187 ++++
frontend/60sapi/实用功能/配色方案/index.html | 64 ++
frontend/60sapi/实用功能/配色方案/script.js | 315 +++++++
frontend/60sapi/实用功能/配色方案/styles.css | 422 +++++++++
.../60sapi/实用功能/配色方案/返回接口.json | 273 ++++++
.../随机密码生成器/css/background.css | 252 +++++
.../实用功能/随机密码生成器/css/style.css | 647 +++++++++++++
.../60sapi/实用功能/随机密码生成器/index.html | 146 +++
.../实用功能/随机密码生成器/js/script.js | 412 ++++++++
.../实用功能/随机密码生成器/返回接口.json | 32 +
.../60sapi/实用功能/随机颜色/background.css | 215 +++++
frontend/60sapi/实用功能/随机颜色/index.html | 187 ++++
frontend/60sapi/实用功能/随机颜色/script.js | 426 +++++++++
frontend/60sapi/实用功能/随机颜色/styles.css | 637 +++++++++++++
.../60sapi/实用功能/随机颜色/返回接口.json | 60 ++
frontend/60sapi/生成要求模板.txt | 1 -
31 files changed, 8796 insertions(+), 9 deletions(-)
create mode 100644 frontend/60sapi/实用功能/实时天气[目前有问题]/background.css
create mode 100644 frontend/60sapi/实用功能/实时天气[目前有问题]/index.html
create mode 100644 frontend/60sapi/实用功能/实时天气[目前有问题]/script.js
create mode 100644 frontend/60sapi/实用功能/实时天气[目前有问题]/styles.css
create mode 100644 frontend/60sapi/实用功能/实时天气[目前有问题]/返回接口.json
create mode 100644 frontend/60sapi/实用功能/密码强度检测/css/style.css
create mode 100644 frontend/60sapi/实用功能/密码强度检测/index.html
create mode 100644 frontend/60sapi/实用功能/密码强度检测/js/script.js
create mode 100644 frontend/60sapi/实用功能/密码强度检测/返回接口.json
delete mode 100755 frontend/60sapi/实用功能/生成要求模板.txt
create mode 100644 frontend/60sapi/实用功能/身体健康分析/background.css
create mode 100644 frontend/60sapi/实用功能/身体健康分析/index.html
create mode 100644 frontend/60sapi/实用功能/身体健康分析/script.js
create mode 100644 frontend/60sapi/实用功能/身体健康分析/styles.css
create mode 100644 frontend/60sapi/实用功能/身体健康分析/返回接口.json
create mode 100644 frontend/60sapi/实用功能/配色方案/background.css
create mode 100644 frontend/60sapi/实用功能/配色方案/index.html
create mode 100644 frontend/60sapi/实用功能/配色方案/script.js
create mode 100644 frontend/60sapi/实用功能/配色方案/styles.css
create mode 100644 frontend/60sapi/实用功能/配色方案/返回接口.json
create mode 100644 frontend/60sapi/实用功能/随机密码生成器/css/background.css
create mode 100644 frontend/60sapi/实用功能/随机密码生成器/css/style.css
create mode 100644 frontend/60sapi/实用功能/随机密码生成器/index.html
create mode 100644 frontend/60sapi/实用功能/随机密码生成器/js/script.js
create mode 100644 frontend/60sapi/实用功能/随机密码生成器/返回接口.json
create mode 100644 frontend/60sapi/实用功能/随机颜色/background.css
create mode 100644 frontend/60sapi/实用功能/随机颜色/index.html
create mode 100644 frontend/60sapi/实用功能/随机颜色/script.js
create mode 100644 frontend/60sapi/实用功能/随机颜色/styles.css
create mode 100644 frontend/60sapi/实用功能/随机颜色/返回接口.json
diff --git a/frontend/60sapi/实用功能/实时天气[目前有问题]/background.css b/frontend/60sapi/实用功能/实时天气[目前有问题]/background.css
new file mode 100644
index 00000000..078de8fa
--- /dev/null
+++ b/frontend/60sapi/实用功能/实时天气[目前有问题]/background.css
@@ -0,0 +1,202 @@
+/* 背景样式文件 - 独立管理背景相关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
new file mode 100644
index 00000000..5a632718
--- /dev/null
+++ b/frontend/60sapi/实用功能/实时天气[目前有问题]/index.html
@@ -0,0 +1,143 @@
+
+
+
+
+
+ 实时天气查询
+
+
+
+
+
+
+
+
+ 正在加载天气数据...
+
+
+
+
+
+
+
+
+ 体感温度
+ --°C
+
+
+ 湿度
+ --%
+
+
+ 风向
+ --
+
+
+ 风力
+ --
+
+
+ 气压
+ -- hPa
+
+
+ 能见度
+ --
+
+
+ 空气质量
+ AQI --
+
+
+ PM2.5
+ -- μg/m³
+
+
+
+
+
+
+
+
获取天气数据失败,请检查网络连接或稍后重试
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/60sapi/实用功能/实时天气[目前有问题]/script.js b/frontend/60sapi/实用功能/实时天气[目前有问题]/script.js
new file mode 100644
index 00000000..bb339d26
--- /dev/null
+++ b/frontend/60sapi/实用功能/实时天气[目前有问题]/script.js
@@ -0,0 +1,354 @@
+// 天气应用主要功能
+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
new file mode 100644
index 00000000..88113f63
--- /dev/null
+++ b/frontend/60sapi/实用功能/实时天气[目前有问题]/styles.css
@@ -0,0 +1,442 @@
+/* 基础样式重置 */
+* {
+ 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
new file mode 100644
index 00000000..671a75a4
--- /dev/null
+++ b/frontend/60sapi/实用功能/实时天气[目前有问题]/返回接口.json
@@ -0,0 +1,68 @@
+{
+ "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
new file mode 100644
index 00000000..858e4bea
--- /dev/null
+++ b/frontend/60sapi/实用功能/密码强度检测/css/style.css
@@ -0,0 +1,878 @@
+/* 基础样式重置 */
+* {
+ 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
new file mode 100644
index 00000000..f9b0c70a
--- /dev/null
+++ b/frontend/60sapi/实用功能/密码强度检测/index.html
@@ -0,0 +1,218 @@
+
+
+
+
+
+
+
+ 🔒 密码强度检测器
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 弱
+ 中等
+ 强
+ 非常强
+
+
+
+
+
+
+
+
+
+
+ 密码长度:
+ -
+
+
+ 熵值:
+ -
+
+
+ 破解时间:
+ -
+
+
+ 字符种类:
+ -
+
+
+
+
+
+
+
+
+
+ ❌
+ 小写字母
+
+
+ ❌
+ 大写字母
+
+
+ ❌
+ 数字
+
+
+ ❌
+ 特殊符号
+
+
+
+
+
+ ⚠️
+ 包含重复字符
+
+
+ ⚠️
+ 包含连续字符
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 🔐
+ 使用密码管理器生成和存储复杂密码
+
+
+ 🔄
+ 为不同账户使用不同的密码
+
+
+ ⏰
+ 定期更换重要账户的密码
+
+
+ 🔒
+ 启用双因素认证(2FA)增强安全性
+
+
+
+
+
+
+
+
+
+
⚠️
+
检测失败
+
请检查网络连接后重试
+
+
+
+
+
+
+
+
+
+ 操作成功
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/60sapi/实用功能/密码强度检测/js/script.js b/frontend/60sapi/实用功能/密码强度检测/js/script.js
new file mode 100644
index 00000000..8861664a
--- /dev/null
+++ b/frontend/60sapi/实用功能/密码强度检测/js/script.js
@@ -0,0 +1,516 @@
+/**
+ * 密码强度检测器
+ * 提供密码强度分析和安全建议
+ */
+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
new file mode 100644
index 00000000..f9eba55a
--- /dev/null
+++ b/frontend/60sapi/实用功能/密码强度检测/返回接口.json
@@ -0,0 +1,37 @@
+{
+ "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/实用功能/生成要求模板.txt b/frontend/60sapi/实用功能/生成要求模板.txt
deleted file mode 100755
index 91b7c04d..00000000
--- a/frontend/60sapi/实用功能/生成要求模板.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-1.生成为静态网页,js,css,html分离出来,不要混合在一起放入html里,难以阅读
-2.网页要适配手机端,电脑端和平板端三个设备分别做不同的css格式,优先优化手机端用户体验
-3.网页默认风格以淡绿色清新风格为主,除非用户要求
-4.尽量不要引用外部css,js,实在要引用就使用中国国内的cdn,否则用户可能加载不出来
-5.返回接口.json储存了网页api返回的数据格式
-6.严格按照用户要求执行,不得随意添加什么注解,如“以下数据来自...”
-7.接口集合.json保存了所有已知的后端API接口,一个访问不了尝试自动切换另一个
-8.在css中有关背景的css单独一个css文件,方便我直接迁移
diff --git a/frontend/60sapi/实用功能/身体健康分析/background.css b/frontend/60sapi/实用功能/身体健康分析/background.css
new file mode 100644
index 00000000..9eb864ab
--- /dev/null
+++ b/frontend/60sapi/实用功能/身体健康分析/background.css
@@ -0,0 +1,243 @@
+/* 背景样式文件 - 独立管理背景相关样式 */
+
+/* 主体背景 */
+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
new file mode 100644
index 00000000..d34d508c
--- /dev/null
+++ b/frontend/60sapi/实用功能/身体健康分析/index.html
@@ -0,0 +1,115 @@
+
+
+
+
+
+ 身体健康分析
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/60sapi/实用功能/身体健康分析/script.js b/frontend/60sapi/实用功能/身体健康分析/script.js
new file mode 100644
index 00000000..d0a440df
--- /dev/null
+++ b/frontend/60sapi/实用功能/身体健康分析/script.js
@@ -0,0 +1,515 @@
+// 身体健康分析 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
new file mode 100644
index 00000000..90fde65a
--- /dev/null
+++ b/frontend/60sapi/实用功能/身体健康分析/styles.css
@@ -0,0 +1,697 @@
+/* 基础样式重置 */
+* {
+ 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
new file mode 100644
index 00000000..455126d6
--- /dev/null
+++ b/frontend/60sapi/实用功能/身体健康分析/返回接口.json
@@ -0,0 +1,93 @@
+{
+ "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
new file mode 100644
index 00000000..13feaa42
--- /dev/null
+++ b/frontend/60sapi/实用功能/配色方案/background.css
@@ -0,0 +1,187 @@
+/* 背景样式文件 - 单独管理所有背景相关样式 */
+
+/* 主体背景 */
+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
new file mode 100644
index 00000000..066b2764
--- /dev/null
+++ b/frontend/60sapi/实用功能/配色方案/index.html
@@ -0,0 +1,64 @@
+
+
+
+
+
+ 配色方案生成器
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/60sapi/实用功能/配色方案/script.js b/frontend/60sapi/实用功能/配色方案/script.js
new file mode 100644
index 00000000..3bf8719f
--- /dev/null
+++ b/frontend/60sapi/实用功能/配色方案/script.js
@@ -0,0 +1,315 @@
+// 配色方案生成器 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 = `
+
+ `;
+ }
+
+ // 显示结果
+ 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.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
new file mode 100644
index 00000000..68225012
--- /dev/null
+++ b/frontend/60sapi/实用功能/配色方案/styles.css
@@ -0,0 +1,422 @@
+/* 基础样式重置 */
+* {
+ 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
new file mode 100644
index 00000000..6f353332
--- /dev/null
+++ b/frontend/60sapi/实用功能/配色方案/返回接口.json
@@ -0,0 +1,273 @@
+{
+ "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/实用功能/随机密码生成器/css/background.css b/frontend/60sapi/实用功能/随机密码生成器/css/background.css
new file mode 100644
index 00000000..4108e5b7
--- /dev/null
+++ b/frontend/60sapi/实用功能/随机密码生成器/css/background.css
@@ -0,0 +1,252 @@
+/* 背景样式文件 */
+
+/* 主背景渐变 */
+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
new file mode 100644
index 00000000..2793ae86
--- /dev/null
+++ b/frontend/60sapi/实用功能/随机密码生成器/css/style.css
@@ -0,0 +1,647 @@
+/* 基础样式重置 */
+* {
+ 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
new file mode 100644
index 00000000..baada2f2
--- /dev/null
+++ b/frontend/60sapi/实用功能/随机密码生成器/index.html
@@ -0,0 +1,146 @@
+
+
+
+
+
+ 随机密码生成器
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 长度:
+ -
+
+
+ 强度:
+ -
+
+
+ 熵值:
+ -
+
+
+ 数字:
+ -
+
+
+ 大写:
+ -
+
+
+ 小写:
+ -
+
+
+ 符号:
+ -
+
+
+ 破解时间:
+ -
+
+
+
+
+
+
+
+
⚠️
+
生成失败
+
请检查网络连接后重试
+
+
+
+
+
+
+
+
+ 密码已复制到剪贴板
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/60sapi/实用功能/随机密码生成器/js/script.js b/frontend/60sapi/实用功能/随机密码生成器/js/script.js
new file mode 100644
index 00000000..a8e56061
--- /dev/null
+++ b/frontend/60sapi/实用功能/随机密码生成器/js/script.js
@@ -0,0 +1,412 @@
+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
new file mode 100644
index 00000000..3b91a5e8
--- /dev/null
+++ b/frontend/60sapi/实用功能/随机密码生成器/返回接口.json
@@ -0,0 +1,32 @@
+{
+ "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
new file mode 100644
index 00000000..81e610a9
--- /dev/null
+++ b/frontend/60sapi/实用功能/随机颜色/background.css
@@ -0,0 +1,215 @@
+/* 背景样式文件 - 独立管理背景相关样式 */
+
+/* 主体背景 */
+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
new file mode 100644
index 00000000..cf9be12c
--- /dev/null
+++ b/frontend/60sapi/实用功能/随机颜色/index.html
@@ -0,0 +1,187 @@
+
+
+
+
+
+ 随机颜色/颜色转换工具
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+
+
+ 0
+
+
+
+ 0
+
+
+
+ #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
new file mode 100644
index 00000000..e641efe4
--- /dev/null
+++ b/frontend/60sapi/实用功能/随机颜色/script.js
@@ -0,0 +1,426 @@
+// 随机颜色/颜色转换工具 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
new file mode 100644
index 00000000..cd53529c
--- /dev/null
+++ b/frontend/60sapi/实用功能/随机颜色/styles.css
@@ -0,0 +1,637 @@
+/* 基础样式重置 */
+* {
+ 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
new file mode 100644
index 00000000..46d731ff
--- /dev/null
+++ b/frontend/60sapi/实用功能/随机颜色/返回接口.json
@@ -0,0 +1,60 @@
+{
+ "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/生成要求模板.txt b/frontend/60sapi/生成要求模板.txt
index 0a3addc7..975a3074 100755
--- a/frontend/60sapi/生成要求模板.txt
+++ b/frontend/60sapi/生成要求模板.txt
@@ -4,5 +4,4 @@
4.尽量不要引用外部css,js,实在要引用就使用中国国内的cdn,否则用户可能加载不出来
5.返回接口.json储存了网页api返回的数据格式
6.严格按照用户要求执行,不得随意添加什么注解,如“以下数据来自...”
-7.接口集合.json保存了所有已知的后端API接口,一个访问不了尝试自动切换另一个
8.在css中有关背景的css单独一个css文件,方便我直接迁移
\ No newline at end of file