桌面应用图标替换为 B-brackets 设计(深藏青 + 白/蓝花括号)
- icon.svg 取自 opsx-icon-options/api/B-brackets.svg,全套光栅重生成: icon.icns(iconutil)、icon.ico(PNG-in-ICO 6 尺寸)、16-1024 PNG、Windows Square*/StoreLogo - 替换 Tauri 脚手架默认五角星图标;GUI 重启实测 Dock 图标已生效 - 服务全量重启:server 8787(官网/文档 200)+ web 5173 + 桌面 GUI
This commit is contained in:
1 parent
71a6d986a4
commit
39f4d5addc
161 files changed
+3289
-515
No files matched your search
@@ -0,0 +1,57 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>OpsxAPI · 路径 B 代理错误分层验收</title>
|
||||
<style>
|
||||
:root { --bg:#0f1419; --text:#e7ecf3; --muted:#8b98a8; --border:#2a3441; --btn:#1e2733; }
|
||||
* { box-sizing: border-box; }
|
||||
body { margin:0; font:13px/1.45 ui-sans-serif,system-ui,sans-serif; background:var(--bg); color:var(--text); padding:24px; }
|
||||
h1 { font-size:16px; margin:0 0 4px; }
|
||||
.sub { color:var(--muted); margin-bottom:20px; }
|
||||
.stack { display:flex; flex-direction:column; gap:14px; max-width:720px; }
|
||||
.banner { border-radius:10px; border:1px solid; padding:12px 14px; }
|
||||
.row { display:flex; align-items:center; gap:8px; margin-bottom:6px; }
|
||||
.pill { display:inline-flex; align-items:center; border-radius:999px; padding:2px 8px; font-size:11px; font-weight:650; ring:1px; }
|
||||
.title { font-weight:650; }
|
||||
.detail { white-space:pre-wrap; opacity:.9; }
|
||||
.actions { display:flex; flex-wrap:wrap; gap:10px; align-items:center; margin-top:10px; }
|
||||
.btn { background:var(--btn); color:var(--text); border:1px solid var(--border); border-radius:8px; padding:5px 10px; font-size:12px; }
|
||||
.link { font-size:12px; opacity:.8; text-decoration:underline; text-underline-offset:2px; background:none; border:0; color:inherit; cursor:pointer; }
|
||||
.proxy { border-color:rgba(245,158,11,.4); background:rgba(245,158,11,.1); }
|
||||
.proxy .pill { background:rgba(245,158,11,.25); color:#fde68a; }
|
||||
.target { border-color:rgba(14,165,233,.4); background:rgba(14,165,233,.1); }
|
||||
.target .pill { background:rgba(14,165,233,.25); color:#bae6fd; }
|
||||
.auth { border-color:rgba(244,63,94,.4); background:rgba(244,63,94,.1); }
|
||||
.auth .pill { background:rgba(244,63,94,.25); color:#fecdd3; }
|
||||
.unknown { border-color:rgba(113,113,122,.45); background:rgba(113,113,122,.12); }
|
||||
.unknown .pill { background:rgba(113,113,122,.35); color:#e4e4e7; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>路径 B · ProxyErrorBanner 中文分层芯片</h1>
|
||||
<div class="sub">线框:代理 / 目标 / 鉴权 · unknown 中性灰 · 主按钮 / 次链接</div>
|
||||
<div class="stack">
|
||||
<div class="banner proxy">
|
||||
<div class="row"><span class="pill">代理</span><span class="title">代理层失败</span></div>
|
||||
<div class="detail">Failed to fetch · ECONNREFUSED 127.0.0.1:8787</div>
|
||||
<div class="actions"><button class="btn">检查本地代理</button><button class="btn">切换桌面直连</button><button class="link">查看通道说明</button></div>
|
||||
</div>
|
||||
<div class="banner target">
|
||||
<div class="row"><span class="pill">目标</span><span class="title">目标服务失败</span></div>
|
||||
<div class="detail">HTTP 502 · ENOTFOUND api.internal.example</div>
|
||||
<div class="actions"><button class="btn">检查 BaseURL / VPN</button></div>
|
||||
</div>
|
||||
<div class="banner auth">
|
||||
<div class="row"><span class="pill">鉴权</span><span class="title">鉴权层失败</span></div>
|
||||
<div class="detail">401 Unauthorized · Bearer 无效</div>
|
||||
<div class="actions"><button class="btn">检查 Token / Auth</button></div>
|
||||
</div>
|
||||
<div class="banner unknown">
|
||||
<div class="row"><span class="pill">未知</span><span class="title">请求失败(请按层排查)</span></div>
|
||||
<div class="detail">Unexpected error</div>
|
||||
<div class="actions"><button class="btn">查代理 :8787</button><button class="btn">切换桌面直连</button><button class="link">查环境 / BaseURL</button></div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,15 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<defs>
|
||||
<linearGradient id="g" x1="0" y1="0" x2="64" y2="64" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#2563EB"/>
|
||||
<stop offset="1" stop-color="#06B6D4"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect width="64" height="64" rx="14" fill="url(#g)"/>
|
||||
<g stroke="#fff" stroke-width="5" stroke-linecap="round" stroke-linejoin="round" fill="none">
|
||||
<path d="M17 25h26"/>
|
||||
<path d="M37 19l6 6-6 6"/>
|
||||
<path d="M47 39H21"/>
|
||||
<path d="M27 33l-6 6 6 6"/>
|
||||
</g>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512">
|
||||
<rect width="512" height="512" rx="112" fill="#0B182C"/>
|
||||
<path d="M200 130c-48 0-70 28-70 70v28c0 22-14 34-34 38v20c20 4 34 16 34 38v28c0 42 22 70 70 70" fill="none" stroke="#FFFFFF" stroke-width="36" stroke-linecap="round"/>
|
||||
<path d="M312 130c48 0 70 28 70 70v28c0 22 14 34 34 38v20c-20 4-34 16-34 38v28c0 42-22 70-70 70" fill="none" stroke="#3B82F6" stroke-width="36" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 564 B After Width: | Height: | Size: 496 B |
+83
-9
@@ -199,7 +199,7 @@
|
||||
border-bottom-color: var(--accent);
|
||||
}
|
||||
.ops-tab .ops-count {
|
||||
@apply ml-1 rounded-full px-1.5 text-[10px];
|
||||
@apply ml-1 rounded-full px-1.5 text-[11px];
|
||||
background: var(--hover);
|
||||
color: var(--text-dim);
|
||||
}
|
||||
@@ -232,7 +232,7 @@
|
||||
.ops-method-HEAD { color: var(--m-HEAD); }
|
||||
.ops-method-OPTIONS { color: var(--m-OPTIONS); }
|
||||
.ops-method-badge {
|
||||
@apply inline-block rounded px-1.5 py-0.5 text-[10px] font-bold tracking-wide;
|
||||
@apply inline-block rounded px-1.5 py-0.5 text-[11px] font-bold tracking-wide;
|
||||
background: var(--hover);
|
||||
}
|
||||
|
||||
@@ -352,7 +352,7 @@
|
||||
.env-dialog-item:hover { background: var(--hover); color: var(--text); }
|
||||
.env-dialog-item.active { background: var(--active); color: var(--accent-strong); }
|
||||
.env-dialog-current {
|
||||
@apply rounded-full px-1.5 py-0.5 text-[10px] font-semibold;
|
||||
@apply rounded-full px-1.5 py-0.5 text-[11px] font-semibold;
|
||||
background: color-mix(in srgb, var(--success) 14%, transparent);
|
||||
color: var(--success);
|
||||
}
|
||||
@@ -442,9 +442,15 @@
|
||||
}
|
||||
.set-toggle.on .set-toggle-dot { transform: translateX(18px); }
|
||||
|
||||
/* Mock 规则表(随右侧内容区整体滚动,表头吸附) */
|
||||
/* Mock 规则表:表内滚动,表头吸顶(避免整窗跟着 60+ 行狂滚) */
|
||||
.set-group .ops-hint { margin: 10px 12px 0; }
|
||||
.mock-rules { @apply mt-2; }
|
||||
.mock-rules {
|
||||
@apply mt-2;
|
||||
max-height: min(42vh, 380px);
|
||||
overflow-y: auto;
|
||||
overscroll-behavior: contain;
|
||||
border-top: 1px solid color-mix(in srgb, var(--border) 55%, transparent);
|
||||
}
|
||||
.mock-rule-head, .mock-rule-row {
|
||||
display: grid;
|
||||
grid-template-columns: 88px 84px minmax(110px, 1fr) minmax(130px, 1.2fr) minmax(96px, 0.9fr) 44px 30px;
|
||||
@@ -453,7 +459,7 @@
|
||||
padding: 4px 12px;
|
||||
}
|
||||
.mock-rule-head {
|
||||
@apply sticky top-0 z-[1] text-[11px] font-semibold;
|
||||
@apply sticky top-0 z-[2] text-[11px] font-semibold;
|
||||
color: var(--text-faint);
|
||||
background: var(--panel-2);
|
||||
border-bottom: 1px solid var(--border);
|
||||
@@ -483,7 +489,7 @@
|
||||
.mock-cheat-item .ops-faint { flex: 1; min-width: 0; @apply truncate; }
|
||||
.mock-cheat-gen {
|
||||
max-width: 46%;
|
||||
@apply truncate font-mono text-[10px];
|
||||
@apply truncate font-mono text-[11px];
|
||||
color: var(--text-faint);
|
||||
}
|
||||
.mock-preview-value {
|
||||
@@ -538,6 +544,29 @@
|
||||
border-radius: 2px;
|
||||
background: var(--accent);
|
||||
}
|
||||
|
||||
/* 工作区角标:绿=本地,蓝=团队 */
|
||||
.rail-ws-badge {
|
||||
position: absolute;
|
||||
right: -2px;
|
||||
bottom: -1px;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 999px;
|
||||
border: 1.5px solid var(--panel);
|
||||
}
|
||||
.rail-ws-badge.local { background: #22c55e; }
|
||||
.rail-ws-badge.team { background: #3b82f6; }
|
||||
.rail-ws-badge.cloud { background: #60a5fa; }
|
||||
.rail-ws-dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 999px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.rail-ws-dot.local { background: #22c55e; }
|
||||
.rail-ws-dot.team { background: #3b82f6; }
|
||||
|
||||
.rail-item.rail-login {
|
||||
background: color-mix(in srgb, var(--accent) 12%, transparent);
|
||||
color: var(--accent-strong);
|
||||
@@ -602,7 +631,7 @@
|
||||
}
|
||||
.member-row:hover { background: var(--panel-2); }
|
||||
.spec-chip {
|
||||
@apply inline-flex shrink-0 items-center rounded-full border px-2 py-px text-[10px] font-medium;
|
||||
@apply inline-flex shrink-0 items-center rounded-full border px-2 py-px text-[11px] font-medium;
|
||||
}
|
||||
.spec-preset {
|
||||
@apply rounded-full border px-2 py-0.5 text-[11px] transition;
|
||||
@@ -628,7 +657,7 @@
|
||||
|
||||
/* ---------- 账号 / 空间 ---------- */
|
||||
.ops-user-avatar {
|
||||
@apply grid h-[18px] w-[18px] shrink-0 place-items-center rounded-full text-[10px] font-bold text-white;
|
||||
@apply grid h-[18px] w-[18px] shrink-0 place-items-center rounded-full text-[11px] font-bold text-white;
|
||||
background: linear-gradient(135deg, var(--accent), var(--accent-strong, var(--accent)));
|
||||
}
|
||||
|
||||
@@ -758,3 +787,48 @@
|
||||
outline: 1.5px dashed var(--accent);
|
||||
outline-offset: -2px;
|
||||
}
|
||||
|
||||
/* === design-system tokens (v1) === */
|
||||
:root {
|
||||
--space-1: 4px;
|
||||
--space-2: 8px;
|
||||
--space-3: 12px;
|
||||
--space-4: 16px;
|
||||
--space-5: 24px;
|
||||
--radius-sm: 6px;
|
||||
--radius-md: 8px;
|
||||
--radius-lg: 12px;
|
||||
--bg-app: var(--bg);
|
||||
--bg-panel: var(--panel);
|
||||
--bg-elevated: var(--panel-2);
|
||||
--code-bg: var(--input-bg);
|
||||
--toolbar-h: 42px;
|
||||
--input-h: 32px;
|
||||
--ws-out: #38bdf8;
|
||||
--ws-in: #34d399;
|
||||
--ws-sys: #94a3b8;
|
||||
--ws-err: #fb7185;
|
||||
}
|
||||
.ops-toolbar { min-height: var(--toolbar-h); }
|
||||
.ops-status-pill {
|
||||
display: inline-flex; align-items: center; gap: 4px;
|
||||
border-radius: 999px; padding: 2px 8px; font-size: 11px; font-weight: 600;
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
.ops-status-2xx { color: var(--success); background: color-mix(in srgb, var(--success) 14%, transparent); border-color: color-mix(in srgb, var(--success) 35%, var(--border)); }
|
||||
.ops-status-3xx { color: var(--accent-strong); background: var(--accent-soft); border-color: color-mix(in srgb, var(--accent) 35%, var(--border)); }
|
||||
.ops-status-4xx { color: var(--warn); background: color-mix(in srgb, var(--warn) 14%, transparent); border-color: color-mix(in srgb, var(--warn) 35%, var(--border)); }
|
||||
.ops-status-5xx { color: var(--danger); background: color-mix(in srgb, var(--danger) 14%, transparent); border-color: color-mix(in srgb, var(--danger) 35%, var(--border)); }
|
||||
.ops-status-idle { color: var(--text-faint); }
|
||||
.ops-msg-out { border-left: 2px solid var(--ws-out); }
|
||||
.ops-msg-in { border-left: 2px solid var(--ws-in); }
|
||||
.ops-msg-sys { border-left: 2px solid var(--ws-sys); }
|
||||
.ops-msg-err { border-left: 2px solid var(--ws-err); }
|
||||
.ops-filter-chip {
|
||||
border: 1px solid var(--border); border-radius: 999px; padding: 2px 8px; font-size: 11px; color: var(--text-dim);
|
||||
background: transparent;
|
||||
}
|
||||
.ops-filter-chip-active { color: var(--accent-strong); border-color: var(--accent); background: var(--accent-soft); }
|
||||
|
||||
/* alias panel-2 */
|
||||
:root, :root[data-theme="dark"], :root[data-theme="light"] { --panel-2: var(--panel-2); --code-bg: var(--input-bg); }
|
||||
@@ -23,6 +23,7 @@ export default defineConfig({
|
||||
"/v1": {
|
||||
target: "http://127.0.0.1:8787",
|
||||
changeOrigin: true,
|
||||
ws: true,
|
||||
},
|
||||
"/health": {
|
||||
target: "http://127.0.0.1:8787",
|
||||
|
||||
Reference in new issue
Block a user