Files
2026-04-16 16:31:48 +08:00

99 lines
6.2 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8"/>
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
<title>FST ToolKit</title>
<style>
/* --- 基础样式 --- */
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial;background:linear-gradient(135deg,#0f172a 0%,#1e293b 100%);padding:20px;min-height:100vh;color:#e2e8f0}
.container{max-width:1200px;margin:0 auto}
h1{text-align:center;margin-bottom:40px;font-size:2.5rem;text-shadow:0 2px 4px rgba(0,0,0,.2)}
.icon-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:30px;padding:20px}
.icon-item{background:rgba(30,41,59,.7);backdrop-filter:blur(10px);border-radius:16px;padding:20px;text-align:center;transition:all .3s ease;cursor:pointer;box-shadow:0 8px 32px rgba(2,8,20,.4);border:1px solid rgba(255,255,255,.08)}
.icon-item:hover{transform:translateY(-8px);box-shadow:0 12px 36px rgba(7,112,219,.25);background:rgba(30,41,59,.9);border-color:rgba(59,130,246,.3)}
.icon-img{width:120px;height:120px;object-fit:contain;margin-bottom:15px;border-radius:16px;background:transparent;padding:12px;box-shadow:0 4px 6px rgba(0,0,0,.1)}
.icon-title{font-size:16px;font-weight:600;color:#f1f5f9;margin-bottom:8px}
.icon-description{font-size:14px;color:#94a3b8;line-height:1.4}
.offline-indicator{position:fixed;top:20px;right:20px;background:rgba(30,41,59,.7);backdrop-filter:blur(10px);color:#94a3b8;padding:10px 20px;border-radius:20px;font-size:14px;display:none;box-shadow:0 4px 6px rgba(0,0,0,.1);border:1px solid rgba(255,255,255,.08);z-index:100}
.offline .offline-indicator{display:block}
/* --- 分割线 --- */
.section-divider{grid-column:1/-1;height:1px;background:linear-gradient(90deg,transparent,rgba(59,130,246,.6),transparent);margin:30px 0 10px;position:relative}
.section-divider::after{content:attr(data-label);position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);background:#0f172a;color:#94a3b8;font-size:calc(13px * var(--divider-scale);padding:0 12px;white-space:nowrap}
@media(max-width:768px){.icon-grid{grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:20px}h1{font-size:2rem}}
</style>
</head>
<body>
<div class="offline-indicator">离线模式</div>
<div class="container">
<h1>FST ToolKit</h1>
<div class="icon-grid" id="iconGrid"></div>
</div>
<script>
// 图标配置新增就加一行group 相同即同组
const iconConfig = [
{title:"FST Data Factory", description:"FST annotate factory", iconUrl:"http://10.204.22.130/logo/fst_an.png", link:"http://10.204.22.142:5221/", group:"Cooperation"},
{title:"VLM Portal (TBD)", description:"Search coner case by text & pic", iconUrl:"http://10.204.22.130/logo/vlm.png", link:"", group:"Cooperation"},
{title:"MB Viz (TBD)", description:"MB self-developed Rosbag Viz tools", iconUrl:"http://10.204.22.130/logo/mbviz.png", link:"", group:"Cooperation"},
{title:"Rosbag Data Browser (TBD)", description:"Search all Rosbags by condition", iconUrl:"http://10.204.22.130/logo/browser.png", link:"", group:"Cooperation"},
{title:"Rosetta", description:"Helix annotate platform", iconUrl:"http://10.204.22.130/logo/rosetta.png", link:"http://rosetta.helix.cn.bg.corpintra.net/", group:"Cooperation"},
{title:"ROOT_DB_API", description:"ROOT DB API Swagger Docs", iconUrl:"http://10.204.22.130/logo/API.png", link:"http://10.204.22.135:30000/apidocs/", group:"Tools"},
{title:"pgAdmin4", description:"Postgres web client", iconUrl:"http://10.204.22.130/logo/pg.png", link:"http://10.204.22.135:30001/", group:"Tools"},
{title:"Grafana", description:"Date monitoring & DashBoard", iconUrl:"http://10.204.22.130/logo/grafana.png", link:"http://10.204.22.135:30002/", group:"Tools"},
{title:"Portainer", description:"Docker manager with UI", iconUrl:"http://10.204.22.130/logo/docker.png", link:"http://10.204.22.135:30003/", group:"Tools"},
{title:"TileServer", description:"Offline map provider", iconUrl:"http://10.204.22.130/logo/tile.png", link:"http://10.204.22.135:30005/", group:"Tools"},
{title:"Vault (TBD)", description:"All accounts & password", iconUrl:"http://10.204.22.130/logo/vault.png", link:"", group:"Tools"},
{title:"FST Test Platform", description:"Algorithm & Models testing", iconUrl:"http://10.204.22.130/logo/test.png", link:"http://10.204.22.130:8080/", group:"Cooperation"}
];
function createIconElement(cfg){
const div = document.createElement('div');
div.className = 'icon-item';
div.onclick = () => window.open(cfg.link, '_blank', 'noopener');
div.innerHTML = `
<img class="icon-img" src="${cfg.iconUrl}" alt="${cfg.title}" onerror="this.src='assets/fallback.svg'"/>
<div class="icon-title">${cfg.title}</div>
<div class="icon-description">${cfg.description}</div>`;
return div;
}
function insertDivider(grid, label){
const div = document.createElement('div');
div.className = 'section-divider';
div.setAttribute('data-label', label);
grid.appendChild(div);
}
function initializePage(){
const grid = document.getElementById('iconGrid');
const groups = {};
iconConfig.forEach(item => {
groups[item.group] = groups[item.group] || [];
groups[item.group].push(item);
});
let first = true;
Object.entries(groups).forEach(([name, arr]) => {
insertDivider(grid, name); // 每条组都先插分割线
arr.forEach(cfg => grid.appendChild(createIconElement(cfg)));
});
}
/* 离线提示 & SW 缓存(可选) */
function updateOnlineStatus(){
document.body.classList.toggle('offline', !navigator.onLine);
}
window.addEventListener('load', () => {
initializePage();
updateOnlineStatus();
});
window.addEventListener('online', updateOnlineStatus);
window.addEventListener('offline', updateOnlineStatus);
if ('serviceWorker' in navigator) {
// 如果本地没有 /sw.js 就把下一行注释掉
//navigator.serviceWorker.register('/sw.js').catch(()=>{});
}
</script>
</body>
</html>