a2ae74d582
- Backend: auth refresh reuse, schedule/retry/sync/agent/files fixes - Frontend: push WS, files ETag browse, vite build assets - Docs: audit/changelog, production deploy gate, bug scan registry B7-77 - Deploy: deploy-production.sh, prune assets, gate logs
184 lines
18 KiB
HTML
184 lines
18 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh-CN" class="dark">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
|
<title>Nexus 重设计预览 — 现代暗色 SaaS</title>
|
|
<script src="/app/vendor/tailwindcss-browser.js"></script>
|
|
<style type="text/tailwindcss">
|
|
@theme {
|
|
--color-brand: oklch(55% 0.2 250);
|
|
--color-brand-light: oklch(75% 0.15 250);
|
|
--color-brand-dark: oklch(35% 0.18 250);
|
|
}
|
|
@custom-variant dark (&:where(.dark, .dark *));
|
|
</style>
|
|
<style>
|
|
:root {
|
|
--bg-page: #f5f5f4; --bg-card: #fafaf9; --bg-surface: #e7e5e4;
|
|
--border: #d6d3d1; --border-input: #a8a29e; --text-primary: #292524;
|
|
--text-secondary: #57534e; --text-muted: #78716c; --text-dim: #a8a29e;
|
|
color-scheme: light dark;
|
|
}
|
|
:root.dark {
|
|
--bg-page: #030712; --bg-card: #111827; --bg-surface: #1f2937;
|
|
--border: #1f2937; --border-input: #374151; --text-primary: #f9fafb;
|
|
--text-secondary: #9ca3af; --text-muted: #6b7280; --text-dim: #4b5563;
|
|
}
|
|
body { background: var(--bg-page); color: var(--text-primary); transition: background .3s,color .3s; font-family: -apple-system,BlinkMacSystemFont,'Segoe UI','PingFang SC','Microsoft YaHei',sans-serif; }
|
|
input,select,textarea{font-family:inherit}
|
|
</style>
|
|
</head>
|
|
<body class="min-h-screen flex">
|
|
<aside class="w-64 shrink-0 flex flex-col border-r" style="background:var(--bg-card);border-color:var(--border)">
|
|
<div class="px-5 py-4 border-b" style="border-color:var(--border)">
|
|
<div class="flex items-center gap-3">
|
|
<div class="w-8 h-8 rounded-lg bg-brand/20 flex items-center justify-center">
|
|
<svg class="w-5 h-5 text-brand-light" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M5 12h14M5 12a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v4a2 2 0 01-2 2M5 12a2 2 0 00-2 2v4a2 2 0 002 2h14a2 2 0 002-2v-4a2 2 0 00-2-2"/></svg>
|
|
</div>
|
|
<span class="text-white font-bold text-lg">Nexus</span>
|
|
</div>
|
|
</div>
|
|
<nav class="flex-1 overflow-y-auto py-3 px-3 space-y-1">
|
|
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm bg-brand/10 text-brand-light font-medium">
|
|
<svg class="w-5 h-5 shrink-0" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6A2.25 2.25 0 016 3.75h2.25A2.25 2.25 0 0110.5 6v2.25a2.25 2.25 0 01-2.25 2.25H6a2.25 2.25 0 01-2.25-2.25V6zm0 15.75A2.25 2.25 0 016 19.5h2.25a2.25 2.25 0 012.25 2.25V24a2.25 2.25 0 01-2.25 2.25H6A2.25 2.25 0 013.75 24v-2.25zM13.5 6a2.25 2.25 0 012.25-2.25H18A2.25 2.25 0 0120.25 6v2.25A2.25 2.25 0 0118 10.5h-2.25a2.25 2.25 0 01-2.25-2.25V6zM13.5 15.75a2.25 2.25 0 012.25-2.25H18a2.25 2.25 0 012.25 2.25V24A2.25 2.25 0 0118 26.25h-2.25A2.25 2.25 0 0113.5 24v-8.25z"/></svg>
|
|
仪表盘
|
|
</a>
|
|
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm" style="color:var(--text-secondary)">
|
|
<svg class="w-5 h-5 shrink-0" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M5.25 14.25h13.5m-13.5 0a3 3 0 01-3-3m3 3a3 3 0 100 6h13.5a3 3 0 100-6m-16.5-3a3 3 0 013-3h13.5a3 3 0 013 3m-19.5 0a4.5 4.5 0 01.9-2.7L5.737 5.1a3.375 3.375 0 012.7-1.35h7.126c1.062 0 2.062.5 2.7 1.35l2.587 3.45a4.5 4.5 0 01.9 2.7"/></svg>
|
|
服务器
|
|
</a>
|
|
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm" style="color:var(--text-secondary)">
|
|
<svg class="w-5 h-5 shrink-0" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 12.75V12A2.25 2.25 0 014.5 9.75h15A2.25 2.25 0 0121.75 12v.75m-8.69-6.44l-2.12-2.12a1.5 1.5 0 00-1.061-.44H4.5A2.25 2.25 0 002.25 6v12a2.25 2.25 0 002.25 2.25h15A2.25 2.25 0 0021.75 18V9a2.25 2.25 0 00-2.25-2.25h-5.379a1.5 1.5 0 01-1.06-.44z"/></svg>
|
|
文件管理
|
|
</a>
|
|
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm" style="color:var(--text-secondary)">
|
|
<svg class="w-5 h-5 shrink-0" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5m-13.5-9L12 3m0 0l4.5 4.5M12 3v13.5"/></svg>
|
|
推送
|
|
</a>
|
|
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm" style="color:var(--text-secondary)">
|
|
<svg class="w-5 h-5 shrink-0" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M17.25 6.75L22.5 12l-5.25 5.25m-10.5 0L1.5 12l5.25-5.25m7.5-3l-4.5 16.5"/></svg>
|
|
脚本库
|
|
</a>
|
|
<div class="border-t my-2" style="border-color:var(--border)"></div>
|
|
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm" style="color:var(--text-secondary)">
|
|
<svg class="w-5 h-5 shrink-0" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M6.75 7.5l3 2.25-3 2.25m4.5 0h3m-9 8.25h13.5A2.25 2.25 0 0021 18V6a2.25 2.25 0 00-2.25-2.25H5.25A2.25 2.25 0 003 6v12a2.25 2.25 0 002.25 2.25z"/></svg>
|
|
命令日志
|
|
</a>
|
|
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm" style="color:var(--text-secondary)">
|
|
<svg class="w-5 h-5 shrink-0" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0"/></svg>
|
|
告警中心
|
|
</a>
|
|
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm" style="color:var(--text-secondary)">
|
|
<svg class="w-5 h-5 shrink-0" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9 12h3.75M9 15h3.75M9 18h3.75m3 .75H18a2.25 2.25 0 002.25-2.25V6.108c0-1.135-.845-2.098-1.976-2.192a48.424 48.424 0 00-1.123-.08m-5.801 0c-.065.21-.1.433-.1.664 0 .414.336.75.75.75h4.5a.75.75 0 00.75-.75 2.25 2.25 0 00-.1-.664m-5.8 0A2.251 2.251 0 0113.5 2.25H15c1.012 0 1.867.668 2.15 1.586m-5.8 0c-.376.023-.75.05-1.124.08C9.095 4.01 8.25 4.973 8.25 6.108V8.25m0 0H4.875c-.621 0-1.125.504-1.125 1.125v11.25c0 .621.504 1.125 1.125 1.125h9.75c.621 0 1.125-.504 1.125-1.125V9.375c0-.621-.504-1.125-1.125-1.125H8.25zM6.75 12h.008v.008H6.75V12zm0 3h.008v.008H6.75V15zm0 3h.008v.008H6.75V18z"/></svg>
|
|
审计日志
|
|
</a>
|
|
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm" style="color:var(--text-secondary)">
|
|
<svg class="w-5 h-5 shrink-0" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.324.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 011.37.49l1.296 2.247a1.125 1.125 0 01-.26 1.431l-1.003.827c-.293.24-.438.613-.431.992a6.759 6.759 0 010 .255c-.007.378.138.75.43.99l1.005.828c.424.35.534.954.26 1.43l-1.298 2.247a1.125 1.125 0 01-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.57 6.57 0 01-.22.128c-.331.183-.581.495-.644.869l-.213 1.28c-.09.543-.56.941-1.11.941h-2.594c-.55 0-1.02-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 01-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 01-1.369-.49l-1.297-2.247a1.125 1.125 0 01.26-1.431l1.004-.827c.292-.24.437-.613.43-.992a6.932 6.932 0 010-.255c.007-.378-.138-.75-.43-.99l-1.004-.828a1.125 1.125 0 01-.26-1.43l1.297-2.247a1.125 1.125 0 011.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.087.22-.128.332-.183.582-.495.644-.869l.214-1.281z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
|
|
设置
|
|
</a>
|
|
</nav>
|
|
<div class="border-t p-4" style="border-color:var(--border)">
|
|
<div class="relative mb-3">
|
|
<svg class="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 pointer-events-none" style="color:var(--text-muted)" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z"/></svg>
|
|
<input type="text" placeholder="搜索..." class="w-full pl-9 pr-3 py-1.5 rounded-lg text-sm border focus:outline-none focus:ring-1 focus:ring-brand" style="background:var(--bg-surface);border-color:var(--border-input);color:var(--text-primary)">
|
|
</div>
|
|
<div class="flex items-center justify-between">
|
|
<div class="flex items-center gap-2">
|
|
<div class="w-7 h-7 rounded-full bg-brand/20 flex items-center justify-center"><span class="text-brand-light text-xs font-bold">A</span></div>
|
|
<span class="text-sm" style="color:var(--text-secondary)">admin</span>
|
|
</div>
|
|
<div class="flex items-center gap-1">
|
|
<button onclick="document.documentElement.classList.toggle('dark')" class="p-1.5 rounded-lg transition hover:opacity-80" style="color:var(--text-muted)" title="切换主题">
|
|
<svg class="w-4 h-4 hidden dark:block" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12 3v2.25m6.364.386l-1.591 1.591M21 12h-2.25m-.386 6.364l-1.591-1.591M12 18.75V21m-4.773-4.227l-1.591 1.591M5.25 12H3m4.227-4.773L5.636 5.636M15.75 12a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0z"/></svg>
|
|
<svg class="w-4 h-4 block dark:hidden" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M21.752 15.002A9.718 9.718 0 0118 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 003 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 009.002-5.998z"/></svg>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</aside>
|
|
|
|
<div class="flex-1 flex flex-col min-w-0">
|
|
<header class="px-6 py-3 flex items-center justify-between border-b" style="background:var(--bg-card);border-color:var(--border)">
|
|
<div class="flex items-center gap-4"><h1 class="text-lg font-semibold" style="color:var(--text-primary)">仪表盘</h1></div>
|
|
<div class="flex items-center gap-3">
|
|
<button class="px-3 py-1.5 rounded-lg text-sm font-medium transition flex items-center gap-1.5" style="background:var(--bg-surface);color:var(--text-secondary)">
|
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0l3.181 3.183a8.25 8.25 0 0013.803-3.7M4.031 9.865a8.25 8.25 0 0113.803-3.7l3.181 3.182"/></svg>刷新
|
|
</button>
|
|
</div>
|
|
</header>
|
|
<main class="flex-1 overflow-y-auto p-6 space-y-6">
|
|
<!-- Stats -->
|
|
<div class="grid grid-cols-2 lg:grid-cols-4 gap-4">
|
|
<div class="rounded-xl border p-5" style="background:var(--bg-card);border-color:var(--border)">
|
|
<div class="text-sm mb-1" style="color:var(--text-secondary)">服务器总数</div>
|
|
<div class="text-3xl font-bold" style="color:var(--text-primary)">8</div>
|
|
</div>
|
|
<div class="rounded-xl border p-5" style="background:var(--bg-card);border-color:var(--border)">
|
|
<div class="text-sm mb-1" style="color:var(--text-secondary)">在线</div>
|
|
<div class="text-3xl font-bold text-emerald-400">1</div>
|
|
</div>
|
|
<div class="rounded-xl border p-5" style="background:var(--bg-card);border-color:var(--border)">
|
|
<div class="text-sm mb-1" style="color:var(--text-secondary)">离线</div>
|
|
<div class="text-3xl font-bold text-red-400">7</div>
|
|
</div>
|
|
<div class="rounded-xl border p-5" style="background:var(--bg-card);border-color:var(--border)">
|
|
<div class="text-sm mb-1" style="color:var(--text-secondary)">告警中</div>
|
|
<div class="text-3xl font-bold text-amber-400">0</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Table Preview -->
|
|
<div class="rounded-xl border overflow-hidden" style="background:var(--bg-card);border-color:var(--border)">
|
|
<div class="px-5 py-3 border-b flex items-center justify-between flex-wrap gap-2" style="border-color:var(--border)">
|
|
<h2 class="font-semibold text-sm" style="color:var(--text-primary)">服务器列表</h2>
|
|
<div class="flex items-center gap-2">
|
|
<select class="px-3 py-1.5 rounded-lg text-sm border focus:outline-none focus:ring-1 focus:ring-brand" style="background:var(--bg-surface);border-color:var(--border-input);color:var(--text-primary)">
|
|
<option>全部分类</option><option>商城</option>
|
|
</select>
|
|
<input type="text" placeholder="搜索..." class="px-3 py-1.5 rounded-lg text-sm border w-40 focus:outline-none focus:ring-1 focus:ring-brand" style="background:var(--bg-surface);border-color:var(--border-input);color:var(--text-primary)">
|
|
<button class="px-3 py-1.5 bg-brand hover:bg-brand-dark text-white text-sm rounded-lg font-medium transition">+ 添加</button>
|
|
</div>
|
|
</div>
|
|
<table class="w-full text-sm">
|
|
<thead style="background:var(--bg-surface);color:var(--text-secondary)">
|
|
<tr><th class="text-left px-4 py-3 text-xs uppercase font-medium">Agent 状态</th><th class="text-left px-4 py-3 text-xs uppercase font-medium">名称</th><th class="text-left px-4 py-3 text-xs uppercase font-medium">地址</th><th class="text-left px-4 py-3 text-xs uppercase font-medium">分类</th><th class="text-right px-4 py-3 text-xs uppercase font-medium">操作</th></tr>
|
|
</thead>
|
|
<tbody class="divide-y" style="border-color:var(--border)">
|
|
<tr class="hover:opacity-80 transition"><td class="px-4 py-3"><span class="inline-flex items-center gap-1.5 text-xs"><span class="w-2 h-2 rounded-full bg-emerald-400"></span><span class="text-emerald-400">在线</span></span></td><td class="px-4 py-3 text-white font-medium">prod-web-01</td><td class="px-4 py-3" style="color:var(--text-secondary)">192.168.1.10:22</td><td class="px-4 py-3" style="color:var(--text-secondary)">商城</td><td class="px-4 py-3 text-right"><a href="#" class="text-brand-light hover:underline text-xs mr-2">终端</a><button class="text-red-400 hover:underline text-xs">删除</button></td></tr>
|
|
<tr class="hover:opacity-80 transition"><td class="px-4 py-3"><span class="inline-flex items-center gap-1.5 text-xs"><span class="w-2 h-2 rounded-full bg-red-400 animate-pulse"></span><span class="text-red-400">离线</span></span></td><td class="px-4 py-3 text-white font-medium">dev-db-01</td><td class="px-4 py-3" style="color:var(--text-secondary)">10.0.0.5:22</td><td class="px-4 py-3" style="color:var(--text-secondary)">--</td><td class="px-4 py-3 text-right"><a href="#" class="text-brand-light hover:underline text-xs mr-2">终端</a><button class="text-red-400 hover:underline text-xs">删除</button></td></tr>
|
|
<tr class="hover:opacity-80 transition"><td class="px-4 py-3"><span class="inline-flex items-center gap-1.5 text-xs"><span class="w-2 h-2 rounded-full bg-slate-600"></span><span style="color:var(--text-muted)">未安装</span></span></td><td class="px-4 py-3 text-white font-medium">new-server-03</td><td class="px-4 py-3" style="color:var(--text-secondary)">172.16.0.8:22</td><td class="px-4 py-3" style="color:var(--text-secondary)">商城</td><td class="px-4 py-3 text-right"><a href="#" class="text-brand-light hover:underline text-xs mr-2">终端</a><button class="text-red-400 hover:underline text-xs">删除</button></td></tr>
|
|
</tbody>
|
|
</table>
|
|
<div class="px-5 py-3 border-t flex items-center justify-between text-xs" style="border-color:var(--border);color:var(--text-muted)">
|
|
<span>共 8 台</span>
|
|
<div class="flex items-center gap-1">
|
|
<button class="px-2 py-1 rounded-lg transition" style="background:var(--bg-surface);color:var(--text-secondary)">←</button>
|
|
<button class="px-2.5 py-1 bg-brand text-white rounded-lg text-xs">1</button>
|
|
<button class="px-2 py-1 rounded-lg transition" style="background:var(--bg-surface);color:var(--text-secondary)">→</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Form Preview -->
|
|
<div class="rounded-xl border p-6 space-y-3 max-w-lg" style="background:var(--bg-card);border-color:var(--border)">
|
|
<h3 class="font-semibold text-sm" style="color:var(--text-primary)">添加服务器 — 表单预览</h3>
|
|
<div class="grid grid-cols-2 gap-3">
|
|
<div><label class="block text-xs mb-1" style="color:var(--text-secondary)">名称 *</label><input class="w-full px-3 py-2 rounded-lg text-sm border focus:outline-none focus:ring-1 focus:ring-brand" style="background:var(--bg-surface);border-color:var(--border-input);color:var(--text-primary)" placeholder="web-server-01"></div>
|
|
<div><label class="block text-xs mb-1" style="color:var(--text-secondary)">地址 *</label><input class="w-full px-3 py-2 rounded-lg text-sm border focus:outline-none focus:ring-1 focus:ring-brand" style="background:var(--bg-surface);border-color:var(--border-input);color:var(--text-primary)" placeholder="192.168.1.10"></div>
|
|
</div>
|
|
<div class="grid grid-cols-3 gap-3">
|
|
<div><label class="block text-xs mb-1" style="color:var(--text-secondary)">SSH端口</label><input class="w-full px-3 py-2 rounded-lg text-sm border focus:outline-none focus:ring-1 focus:ring-brand" style="background:var(--bg-surface);border-color:var(--border-input);color:var(--text-primary)" value="22"></div>
|
|
<div><label class="block text-xs mb-1" style="color:var(--text-secondary)">用户名</label><input class="w-full px-3 py-2 rounded-lg text-sm border focus:outline-none focus:ring-1 focus:ring-brand" style="background:var(--bg-surface);border-color:var(--border-input);color:var(--text-primary)" value="root"></div>
|
|
<div><label class="block text-xs mb-1" style="color:var(--text-secondary)">认证</label><select class="w-full px-3 py-2 rounded-lg text-sm border focus:outline-none focus:ring-1 focus:ring-brand" style="background:var(--bg-surface);border-color:var(--border-input);color:var(--text-primary)"><option>密码</option><option>密钥</option></select></div>
|
|
</div>
|
|
<div class="flex gap-2 pt-2">
|
|
<button class="px-4 py-2 bg-brand hover:bg-brand-dark text-white text-sm rounded-lg font-medium transition">保存</button>
|
|
<button class="px-4 py-2 rounded-lg text-sm font-medium transition" style="background:var(--bg-surface);color:var(--text-secondary)">取消</button>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
</body>
|
|
</html>
|