Refine web UI and usage docs

This commit is contained in:
2026-04-14 13:54:02 +08:00
parent 0ba4fef55e
commit 0c01b91fd7
13 changed files with 21990 additions and 18993 deletions
+97 -90
View File
@@ -76,9 +76,10 @@
max-width: 1200px;
margin: 24px auto;
padding: 0 16px 32px;
}
.page-card {
padding: 16px;
display: grid;
grid-template-columns: 220px minmax(0, 1fr);
gap: 12px;
align-items: start;
}
.card {
background: var(--card);
@@ -134,6 +135,9 @@
margin-top: 12px;
flex-wrap: wrap;
}
.btns + .sub {
margin-top: 10px;
}
button {
border: 0;
border-radius: 10px;
@@ -160,6 +164,9 @@
display: grid;
gap: 12px;
}
.brand-toolbar + .sub {
margin-top: 10px;
}
.brand-toolbar-row {
display: grid;
grid-template-columns: repeat(5, minmax(0, 1fr));
@@ -229,10 +236,22 @@
border-top: 1px dashed var(--line);
}
.source-order-wrap {
border: 1px solid var(--line);
border-radius: 10px;
background: #fbfcff;
padding: 10px;
display: grid;
gap: 10px;
}
.source-order-toolbar {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px 16px;
flex-wrap: wrap;
}
.source-order-toolbar .btns {
margin-top: 0;
}
.source-order-toolbar .sub {
margin: 0;
font-size: 14px;
}
.source-order-list {
list-style: none;
@@ -243,14 +262,15 @@
}
.source-order-item {
border: 1px solid #cfd9ea;
border-radius: 10px;
border-radius: 12px;
background: #fff;
padding: 8px 10px;
padding: 12px 14px;
display: grid;
grid-template-columns: 18px 48px 1fr;
gap: 10px;
grid-template-columns: 18px 56px minmax(0, 1fr);
gap: 12px;
align-items: center;
cursor: grab;
box-shadow: 0 4px 12px rgba(36, 56, 89, 0.04);
}
.source-order-item.dragging {
opacity: 0.45;
@@ -261,35 +281,34 @@
}
.drag-handle {
color: #7d8ea8;
font-size: 14px;
font-size: 16px;
user-select: none;
letter-spacing: 1px;
}
.source-rank {
font-size: 12px;
font-size: 13px;
font-weight: 700;
color: #3a5a8b;
background: #edf4ff;
border: 1px solid #cadeff;
border-radius: 999px;
padding: 2px 8px;
padding: 5px 10px;
text-align: center;
}
.source-name {
font-size: 13px;
font-size: 15px;
color: #1f355a;
word-break: break-all;
}
.manage-layout {
margin-top: 14px;
display: grid;
grid-template-columns: 180px 1fr;
gap: 12px;
align-items: start;
}
.manage-tabs {
display: grid;
gap: 8px;
position: sticky;
top: calc(var(--nav-height) + 20px);
padding: 12px;
}
.manage-content {
min-width: 0;
}
.tab-btn {
width: 100%;
@@ -308,10 +327,10 @@
}
.panel-stack {
display: grid;
gap: 12px;
gap: 10px;
}
.section-card {
padding: 16px;
padding: 14px;
}
.section-card .title:last-child,
.section-card .sub:last-child {
@@ -354,9 +373,9 @@
background: #fbfcff;
}
.collapse-body {
padding: 14px 16px 16px;
padding: 12px 14px 14px;
display: grid;
gap: 14px;
gap: 10px;
}
.sync-log {
min-height: 240px;
@@ -374,27 +393,37 @@
min-height: 180px;
}
.sync-schedule-card {
margin: 14px 0;
padding: 12px;
margin: 0;
padding: 10px 12px;
border: 1px solid var(--line);
border-radius: 12px;
background: #fbfcff;
}
.sync-schedule-card .title {
margin-bottom: 10px;
font-size: 15px;
}
.sync-schedule-grid {
display: grid;
grid-template-columns: minmax(220px, 280px) minmax(180px, 240px);
gap: 12px;
gap: 10px;
align-items: end;
}
.sync-schedule-grid .full-row {
grid-column: 1 / -1;
}
.sync-schedule-card .btns {
margin-top: 10px;
}
.sync-schedule-card .btns + .sub {
margin-top: 8px;
}
.check-row {
display: flex;
align-items: center;
gap: 8px;
margin: 0;
min-height: 42px;
min-height: 38px;
}
.check-row input {
width: 16px;
@@ -455,8 +484,6 @@
border-radius: 10px;
background: #fcfdff;
padding: 12px;
}
.modal-list-grid {
display: grid;
gap: 10px;
}
@@ -534,7 +561,7 @@
flex: 0 0 auto;
}
@media (max-width: 1020px) {
.manage-layout {
.wrap {
grid-template-columns: 1fr;
}
.manage-tabs {
@@ -546,6 +573,12 @@
.brand-toolbar-row {
grid-template-columns: 1fr;
}
.source-order-toolbar {
align-items: stretch;
}
.source-order-toolbar .btns {
width: 100%;
}
.brand-toolbar-btn,
.brand-toolbar-btn.stat-btn,
.brand-toolbar-btn.action-btn {
@@ -573,19 +606,14 @@
</nav>
<div class="wrap">
<section class="card page-card">
<h1 class="title">数据管理</h1>
<p class="sub page-sub">把常用操作留在前面,把低频说明收起来。</p>
<aside class="card manage-tabs">
<button id="tabBrandBtn" type="button" class="tab-btn active">品牌列表</button>
<button id="tabSourceBtn" type="button" class="tab-btn">数据来源</button>
<button id="tabSyncBtn" type="button" class="tab-btn">原始数据同步</button>
<button id="tabIndexBtn" type="button" class="tab-btn">索引数据</button>
</aside>
<div class="manage-layout">
<aside class="manage-tabs">
<button id="tabBrandBtn" type="button" class="tab-btn active">品牌列表</button>
<button id="tabSourceBtn" type="button" class="tab-btn">数据来源</button>
<button id="tabSyncBtn" type="button" class="tab-btn">原始数据同步</button>
<button id="tabIndexBtn" type="button" class="tab-btn">索引数据</button>
</aside>
<div class="manage-content">
<div class="manage-content">
<section id="brandTabPanel" class="manage-panel">
<div class="panel-stack">
<article class="card section-card">
@@ -622,18 +650,15 @@
<section id="sourceTabPanel" class="manage-panel hidden">
<div class="panel-stack">
<article class="card section-card">
<h3 class="title">数据来源排序</h3>
<p class="sub">拖拽调整优先级,越靠前权重越高。</p>
<div class="btns">
<button id="saveSourceOrderBtn" type="button" class="primary">保存来源排序</button>
<button id="resetSourceOrderBtn" type="button">重置来源排序</button>
</div>
<div id="sourceOrderStats" class="sub">来源列表未加载。</div>
</article>
<article class="card section-card">
<div class="source-order-wrap">
<div class="source-order-toolbar">
<div class="btns">
<button id="saveSourceOrderBtn" type="button" class="primary">保存来源排序</button>
<button id="resetSourceOrderBtn" type="button">重置来源排序</button>
</div>
<div id="sourceOrderStats" class="sub">来源列表未加载。</div>
</div>
<ul id="sourceOrderList" class="source-order-list">
<li class="sub">暂无来源数据</li>
</ul>
@@ -644,21 +669,11 @@
<section id="syncTabPanel" class="manage-panel hidden">
<div class="panel-stack">
<article class="card section-card">
<h3 class="title">原始数据同步</h3>
<ul class="compact-note-list">
<li>从上游拉取原始 markdown,并重建 <code>dist/device_index.json</code></li>
<li>如果已开启 MySQL 自动装载,同步时也会刷新 MySQL。</li>
<li>开始前请确认完整服务已经启动。</li>
</ul>
</article>
<details class="card collapse-card">
<summary>同步配置</summary>
<details class="card collapse-card" open>
<summary>配置</summary>
<div class="collapse-body">
<div class="sync-schedule-card">
<h4 class="title">MySQL 自动装载</h4>
<p class="sub">控制同步任务和容器后续启动时是否自动导入 schema 与 seed。</p>
<div class="sync-schedule-grid">
<label class="check-row">
<input id="mysqlAutoLoadEnabled" type="checkbox" />
@@ -673,7 +688,6 @@
<div class="sync-schedule-card">
<h4 class="title">外部 MySQL 初始化</h4>
<p class="sub">面向关闭自动装载的外部 MySQL,需要时再执行。</p>
<div class="btns">
<button id="initMysqlBtn" type="button">初始化外部 MySQL</button>
</div>
@@ -681,7 +695,6 @@
<div class="sync-schedule-card">
<h4 class="title">每日自动同步</h4>
<p class="sub">按固定时间自动拉取上游并重建索引与 MySQL Seed。</p>
<div class="sync-schedule-grid">
<label class="check-row">
<input id="scheduleEnabled" type="checkbox" />
@@ -712,7 +725,7 @@
<div id="syncStatus" class="sub">正在检测同步能力。</div>
</article>
<details class="card collapse-card">
<details class="card collapse-card" open>
<summary>任务日志</summary>
<div class="collapse-body">
<pre id="syncLog" class="sync-log compact mono">暂无同步记录</pre>
@@ -724,14 +737,12 @@
<section id="indexTabPanel" class="manage-panel hidden">
<div class="panel-stack">
<article class="card section-card">
<h3 class="title">索引数据</h3>
<p class="sub">查看当前索引加载状态,并在需要时手动刷新。</p>
<div class="btns">
<button id="reloadIndexBtn" type="button" class="primary">重新加载索引</button>
</div>
<div id="indexStatus" class="sub">索引尚未加载。</div>
</article>
<details class="card collapse-card">
<details class="card collapse-card" open>
<summary>索引详情</summary>
<div class="collapse-body">
<pre id="indexSummary" class="sync-log compact mono">暂无索引信息</pre>
@@ -739,9 +750,7 @@
</details>
</div>
</section>
</div>
</div>
</section>
</div>
</div>
<div id="brandModalBackdrop" class="modal-backdrop hidden">
@@ -1449,21 +1458,19 @@
}
brandModalListEl.innerHTML = `
<div class="modal-list-grid">
${items.map((item) => `
<section class="modal-list-item">
<div class="modal-list-head">
<div class="modal-list-title">${escapeHtml(item.title || "-")}</div>
${item.meta ? `<div class="modal-list-meta">${escapeHtml(item.meta)}</div>` : ""}
${items.map((item) => `
<section class="modal-list-item">
<div class="modal-list-head">
<div class="modal-list-title">${escapeHtml(item.title || "-")}</div>
${item.meta ? `<div class="modal-list-meta">${escapeHtml(item.meta)}</div>` : ""}
</div>
${item.tags && item.tags.length ? `
<div class="modal-list-tags">
${item.tags.map((tag) => `<span class="tag">${escapeHtml(tag)}</span>`).join("")}
</div>
${item.tags && item.tags.length ? `
<div class="modal-list-tags">
${item.tags.map((tag) => `<span class="tag">${escapeHtml(tag)}</span>`).join("")}
</div>
` : ""}
</section>
`).join("")}
</div>
` : ""}
</section>
`).join("")}
`;
}