You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
261 lines
7.7 KiB
261 lines
7.7 KiB
<!DOCTYPE html>
|
|
<html lang="zh-CN">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Tool Hub</title>
|
|
|
|
<link rel="icon" type="image/svg+xml"
|
|
href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Crect width='100' height='100' fill='%230b0f14'/%3E%3Crect x='20' y='20' width='20' height='20' fill='%232563eb'/%3E%3Crect x='60' y='20' width='20' height='20' fill='%232563eb'/%3E%3Crect x='20' y='60' width='20' height='20' fill='%232563eb'/%3E%3Crect x='60' y='60' width='20' height='20' fill='%232563eb'/%3E%3C/svg%3E">
|
|
|
|
<style>
|
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
|
|
body {
|
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial;
|
|
background: radial-gradient(circle at top, #111827, #0b0f14);
|
|
color: #e5e7eb;
|
|
min-height: 100vh;
|
|
}
|
|
|
|
.container {
|
|
max-width: 1080px;
|
|
margin: 0 auto;
|
|
padding: 56px 24px 60px;
|
|
}
|
|
|
|
.header {
|
|
text-align: center;
|
|
padding: 0 0 48px;
|
|
}
|
|
|
|
.header h1 {
|
|
font-size: 44px;
|
|
font-weight: 700;
|
|
letter-spacing: 2px;
|
|
margin-bottom: 10px;
|
|
background: linear-gradient(135deg, #60a5fa 0%, #3b82f6 50%, #818cf8 100%);
|
|
-webkit-background-clip: text;
|
|
-webkit-text-fill-color: transparent;
|
|
background-clip: text;
|
|
}
|
|
|
|
.header p {
|
|
color: #6b7280;
|
|
font-size: 15px;
|
|
letter-spacing: 0.5px;
|
|
}
|
|
|
|
.grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(3, 1fr);
|
|
gap: 20px;
|
|
}
|
|
|
|
.card {
|
|
display: block;
|
|
background: rgba(255,255,255,0.03);
|
|
border: 1px solid rgba(255,255,255,0.08);
|
|
border-radius: 16px;
|
|
padding: 26px 24px;
|
|
transition: transform 0.25s ease, border-color 0.25s ease, box-shadow 0.25s ease;
|
|
backdrop-filter: blur(10px);
|
|
text-decoration: none;
|
|
color: inherit;
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.card::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
height: 2px;
|
|
background: linear-gradient(90deg, transparent, rgba(59,130,246,0.6), transparent);
|
|
opacity: 0;
|
|
transition: opacity 0.25s ease;
|
|
}
|
|
|
|
.card:hover {
|
|
transform: translateY(-5px);
|
|
border-color: rgba(59,130,246,0.4);
|
|
box-shadow: 0 16px 40px rgba(0,0,0,0.45), 0 0 0 1px rgba(59,130,246,0.1);
|
|
}
|
|
|
|
.card:hover::before {
|
|
opacity: 1;
|
|
}
|
|
|
|
.card-icon {
|
|
font-size: 20px;
|
|
margin-right: 8px;
|
|
}
|
|
|
|
.card h3 {
|
|
font-size: 17px;
|
|
font-weight: 600;
|
|
color: #f3f4f6;
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.card p {
|
|
font-size: 13px;
|
|
color: #6b7280;
|
|
line-height: 1.6;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.btn {
|
|
display: inline-block;
|
|
padding: 7px 14px;
|
|
font-size: 13px;
|
|
border-radius: 8px;
|
|
background: rgba(37,99,235,0.2);
|
|
color: #60a5fa;
|
|
border: 1px solid rgba(37,99,235,0.3);
|
|
font-weight: 500;
|
|
transition: all 0.2s;
|
|
}
|
|
|
|
.btn:hover {
|
|
background: rgba(37,99,235,0.35);
|
|
color: #93c5fd;
|
|
}
|
|
|
|
.toast {
|
|
position: fixed;
|
|
right: 24px;
|
|
bottom: 24px;
|
|
background: rgba(17,24,39,0.95);
|
|
color: #e5e7eb;
|
|
padding: 12px 18px;
|
|
border-radius: 12px;
|
|
border: 1px solid rgba(255,255,255,0.1);
|
|
font-size: 14px;
|
|
opacity: 0;
|
|
transform: translateY(10px);
|
|
transition: all 0.25s ease;
|
|
z-index: 9999;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.toast.show { opacity: 1; transform: translateY(0); }
|
|
|
|
/* ---- 响应式 ---- */
|
|
|
|
/* 平板横屏 */
|
|
@media (max-width: 900px) {
|
|
.grid { grid-template-columns: repeat(2, 1fr); }
|
|
.container { padding: 40px 20px 50px; }
|
|
.header h1 { font-size: 36px; }
|
|
.card { padding: 22px 20px; }
|
|
}
|
|
|
|
/* 手机 */
|
|
@media (max-width: 540px) {
|
|
.grid { grid-template-columns: 1fr; gap: 14px; }
|
|
.container { padding: 30px 16px 40px; }
|
|
.header { padding-bottom: 36px; }
|
|
.header h1 { font-size: 28px; }
|
|
.header p { font-size: 13px; }
|
|
.card { padding: 20px 18px; }
|
|
.card-icon { font-size: 24px; }
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<body>
|
|
<div class="container">
|
|
|
|
<div class="header">
|
|
<h1>Tool Hub</h1>
|
|
<p>Minimal Engineering Tools · Lightweight · Extensible</p>
|
|
</div>
|
|
|
|
<div class="grid">
|
|
|
|
<a class="card" href="{{ url_for('tool', name='excel') }}" target="_blank" rel="noopener noreferrer">
|
|
<h3><span class="card-icon">📊</span> Excel 合并工具</h3>
|
|
<p>CSV / XLSX 数据合并分析</p>
|
|
<span class="btn">进入</span>
|
|
</a>
|
|
|
|
<a class="card" href="{{ url_for('tool', name='temp_upload') }}" target="_blank" rel="noopener noreferrer">
|
|
<h3><span class="card-icon">📂</span> 临时文件工具</h3>
|
|
<p>上传 / 暂存 / 下载</p>
|
|
<span class="btn">进入</span>
|
|
</a>
|
|
|
|
<a class="card" href="{{ url_for('tool', name='smart_data_v2') }}" target="_blank" rel="noopener noreferrer">
|
|
<h3><span class="card-icon">🧠</span> 数据对比 / 去重 / 筛选</h3>
|
|
<p>多格式数据解析,自动识别字段结构与关联键</p>
|
|
<span class="btn">进入</span>
|
|
</a>
|
|
|
|
<a class="card" href="{{ url_for('tool', name='file_convert') }}" target="_blank" rel="noopener noreferrer">
|
|
<h3><span class="card-icon">📁</span> 文件格式转换工具</h3>
|
|
<p>Excel / CSV / TXT 格式互转,一键导出</p>
|
|
<span class="btn">进入</span>
|
|
</a>
|
|
|
|
<a class="card" href="{{ url_for('tool', name='weekly_permission') }}" target="_blank" rel="noopener noreferrer">
|
|
<h3><span class="card-icon">📌</span> 每周动态授权工具</h3>
|
|
<p>中心 + 工号 → 自动生成权限 SQL</p>
|
|
<span class="btn">进入</span>
|
|
</a>
|
|
|
|
<!--
|
|
<a class="card" href="{{ url_for('tool', name='mail_notify') }}" target="_blank" rel="noopener noreferrer">
|
|
<h3><span class="card-icon">📧</span> 邮件群发工具</h3>
|
|
<p>TXT 解析账号列表 + SMTP 批量通知发送</p>
|
|
<span class="btn">进入</span>
|
|
</a>
|
|
-->
|
|
|
|
<a class="card" href="{{ url_for('tool', name='base64') }}" target="_blank" rel="noopener noreferrer">
|
|
<h3><span class="card-icon">🔐</span> Base64 编解码</h3>
|
|
<p>文本 Base64 编码解码,一键复制结果</p>
|
|
<span class="btn">进入</span>
|
|
</a>
|
|
|
|
<a class="card" href="{{ url_for('tool', name='json') }}" target="_blank" rel="noopener noreferrer">
|
|
<h3><span class="card-icon">📋</span> JSON 格式化工具</h3>
|
|
<p>格式化 / 压缩 / 校验,一键复制</p>
|
|
<span class="btn">进入</span>
|
|
</a>
|
|
|
|
<a class="card" href="{{ url_for('tool', name='url') }}" target="_blank" rel="noopener noreferrer">
|
|
<h3><span class="card-icon">🔗</span> URL 编解码</h3>
|
|
<p>URL 编码解码,开发者刚需工具</p>
|
|
<span class="btn">进入</span>
|
|
</a>
|
|
|
|
<a class="card" href="{{ url_for('tool', name='image_compress') }}" target="_blank" rel="noopener noreferrer">
|
|
<h3><span class="card-icon">🖼️</span> 图片压缩工具</h3>
|
|
<p>JPG/PNG/WEBP 图片压缩,保持清晰度</p>
|
|
<span class="btn">进入</span>
|
|
</a>
|
|
|
|
<a class="card" href="{{ url_for('tool', name='text_diff') }}" target="_blank" rel="noopener noreferrer">
|
|
<h3><span class="card-icon">📝</span> 文本差异对比</h3>
|
|
<p>两段文本对比,高亮显示差异</p>
|
|
<span class="btn">进入</span>
|
|
</a>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<div class="toast" id="toast"></div>
|
|
|
|
<script>
|
|
function showToast(msg) {
|
|
const t = document.getElementById('toast');
|
|
t.innerText = msg;
|
|
t.classList.add('show');
|
|
setTimeout(() => t.classList.remove('show'), 1800);
|
|
}
|
|
</script>
|
|
</body>
|
|
</html> |