From 0bdd88ba9cd2233ecc422f3aa0c3324cbb0c932b Mon Sep 17 00:00:00 2001
From: QiuSW <105186638@qq.com>
Date: Wed, 12 Aug 2026 10:56:07 +0800
Subject: [PATCH] feat: align Bell prototype with go-admin-ui (#31)
---
prototypes/README.md | 11 +-
prototypes/assets/app.js | 30 +--
.../sense.js => assets/go-admin-shell.js} | 20 +-
prototypes/assets/go-admin-ui.css | 182 ++++++++++++++++++
prototypes/bell/bell.css | 33 ++++
prototypes/bell/index.html | 130 ++++++++++---
prototypes/sense/go-admin-ui.css | 181 -----------------
prototypes/sense/index.html | 8 +-
8 files changed, 350 insertions(+), 245 deletions(-)
rename prototypes/{sense/sense.js => assets/go-admin-shell.js} (65%)
create mode 100644 prototypes/assets/go-admin-ui.css
create mode 100644 prototypes/bell/bell.css
delete mode 100644 prototypes/sense/go-admin-ui.css
diff --git a/prototypes/README.md b/prototypes/README.md
index 7f5604c..2051fdf 100644
--- a/prototypes/README.md
+++ b/prototypes/README.md
@@ -16,8 +16,8 @@ python -m http.server 4173 --directory prototypes
- `sense/index.html`:设备接入、ONVIF/RTSP、MediaMTX、实时监看和区域配置;直接映射 go-admin-ui 与 Element Plus 的通用管理端组件。
- `brain/index.html`:合成输入到项目内匿名事件的内部流水线;Brain 无客户管理 UI。
-- `bell/index.html`:合成事件、不可变 Event、规则/Alert、ack/close 和审计时间线。
-- `assets/`:三套原型复用的样式和交互脚本。
+- `bell/index.html`:合成事件、不可变 Event、规则/Alert、ack/close 和审计时间线;直接映射 go-admin-ui 与 Element Plus 的通用管理端组件。
+- `assets/`:三套原型复用的基础样式和交互脚本;Sense/Bell 共同复用 go-admin-ui 原型外壳适配器。
- `design-system/yovision/MASTER.md`:由 UI/UX Pro Max 生成的设计系统基线。
## 交互提示
@@ -28,13 +28,16 @@ python -m http.server 4173 --directory prototypes
- Bell 可注入合成事件,并演示 Alert 的 ack 和 close。
- 所有弹窗支持 `Esc` 关闭,交互元素支持键盘焦点。
-## Sense 的 go-admin-ui 对齐基线
+## Sense / Bell 的 go-admin-ui 对齐基线
- 只读参考仓库:`D:\github\goadmin\go-admin-ui`。
- 参考 commit:`67d393d713877572fab0b897296a4c1d525fc81d`。
- 应用外壳映射:`Sidebar`、`Navbar`、`TagsView`、`AppMain` 和 `BasicLayout` / 页面容器。
- 通用组件映射:Element Plus 的 Button、Form、Input/Select、Table、Pagination、Dialog 和 Tag,以及 go-admin-ui 的搜索区与 `v-permisaction` 权限按钮模式。
-- Sense 专用组件:视频舞台 `SenseVideoStage` 与区域画布 `SenseZoneCanvas`;正式实现前先确认 go-admin-ui 内没有等价组件。
+- 共用原型适配器:`assets/go-admin-ui.css` 与 `assets/go-admin-shell.js`;两套产品不复制应用外壳和通用组件原型代码。
+- Sense 专用组件:视频舞台 `SenseVideoStage` 与区域画布 `SenseZoneCanvas`。
+- Bell 专用组件:值班处置工作台 `AlertWorkbench` 与审计时间线 `AlertAuditTimeline`。
+- 新增专用组件前必须先确认 go-admin-ui / Element Plus 中没有等价组件。
- 原型仍是无构建依赖的 HTML/CSS/JavaScript,并未嵌入或复制 go-admin-ui / Element Plus 源码;这些名称用于约束正式 Vue 实现的组件落点。
## 事实来源边界
diff --git a/prototypes/assets/app.js b/prototypes/assets/app.js
index edcb6b3..82561d0 100644
--- a/prototypes/assets/app.js
+++ b/prototypes/assets/app.js
@@ -148,14 +148,16 @@
});
qs("[data-action='inject-event']")?.addEventListener("click", (event) => {
- event.currentTarget.disabled = true;
- event.currentTarget.textContent = "注入中…";
+ const button = event.currentTarget;
+ const idleText = button.textContent;
+ button.disabled = true;
+ button.textContent = "注入中…";
window.setTimeout(() => {
const count = qs("[data-alert-count]");
if (count) count.textContent = String(Number(count.textContent) + 1);
- event.currentTarget.disabled = false;
- event.currentTarget.textContent = "注入合成事件";
- closeModal(event.currentTarget.closest(".modal-backdrop"));
+ button.disabled = false;
+ button.textContent = idleText;
+ closeModal(button.closest(".modal-backdrop"));
toast("合成事件已校验并生成新的 Alert");
}, 520);
});
@@ -165,7 +167,7 @@
const closeButton = qs("[data-action='close-alert']");
ackButton?.addEventListener("click", () => {
alertState.textContent = "已确认";
- alertState.className = "status status-warning";
+ alertState.className = "status status-warning el-tag";
ackButton.disabled = true;
closeButton.disabled = false;
const timeline = qs("[data-alert-timeline]");
@@ -174,7 +176,7 @@
});
closeButton?.addEventListener("click", () => {
alertState.textContent = "已关闭";
- alertState.className = "status status-success";
+ alertState.className = "status status-success el-tag";
closeButton.disabled = true;
qs("[data-alert-timeline]")?.insertAdjacentHTML("beforeend", `
处置完成并关闭
刚刚 · 原始 Event 保持不变
`);
toast("Alert 已关闭,原始 Event 未修改");
@@ -186,12 +188,14 @@
toast(`已选择:${row.dataset.selectAlert}`);
};
row.addEventListener("click", select);
- row.addEventListener("keydown", (event) => {
- if (event.key === "Enter" || event.key === " ") {
- event.preventDefault();
- select();
- }
- });
+ if (row.tagName !== "BUTTON") {
+ row.addEventListener("keydown", (event) => {
+ if (event.key === "Enter" || event.key === " ") {
+ event.preventDefault();
+ select();
+ }
+ });
+ }
});
const initial = qs("[data-view-target].active")?.dataset.viewTarget || qs("[data-view]")?.dataset.view;
diff --git a/prototypes/sense/sense.js b/prototypes/assets/go-admin-shell.js
similarity index 65%
rename from prototypes/sense/sense.js
rename to prototypes/assets/go-admin-shell.js
index 505163d..7588340 100644
--- a/prototypes/sense/sense.js
+++ b/prototypes/assets/go-admin-shell.js
@@ -3,8 +3,6 @@
const shell = document.querySelector("[data-go-admin-shell]");
const collapse = document.querySelector("[data-collapse-sidebar]");
- const queryForm = document.querySelector("[data-device-query]");
- const queryInput = document.querySelector("#device-filter");
function syncTags(viewName) {
document.querySelectorAll(".tags-view-item").forEach((tag) => {
@@ -27,17 +25,17 @@
});
}
- if (queryForm) {
- queryForm.addEventListener("submit", (event) => {
+ document.querySelectorAll("[data-go-admin-query]").forEach((form) => {
+ const input = document.querySelector(form.dataset.queryInput || "");
+ form.addEventListener("submit", (event) => {
event.preventDefault();
- if (queryInput) queryInput.dispatchEvent(new Event("input", { bubbles: true }));
+ input?.dispatchEvent(new Event("input", { bubbles: true }));
});
- queryForm.addEventListener("reset", () => {
- window.setTimeout(() => {
- if (queryInput) queryInput.dispatchEvent(new Event("input", { bubbles: true }));
- }, 0);
+ form.addEventListener("reset", () => {
+ window.setTimeout(() => input?.dispatchEvent(new Event("input", { bubbles: true })), 0);
});
- }
+ });
- syncTags("overview");
+ const initialView = document.querySelector("[data-view-target].active")?.dataset.viewTarget;
+ if (initialView) syncTags(initialView);
})();
diff --git a/prototypes/assets/go-admin-ui.css b/prototypes/assets/go-admin-ui.css
new file mode 100644
index 0000000..929d345
--- /dev/null
+++ b/prototypes/assets/go-admin-ui.css
@@ -0,0 +1,182 @@
+/*
+ * Shared prototype adapter for go-admin-ui commit 67d393d713877572fab0b897296a4c1d525fc81d.
+ * This is an offline visual/interaction mapping, not copied framework CSS and not an Element Plus runtime.
+ */
+.go-admin-prototype {
+ --ga-primary: #1677ff;
+ --ga-primary-hover: #409eff;
+ --ga-sidebar: #001529;
+ --ga-sidebar-hover: #000c17;
+ --ga-app-bg: #f0f2f5;
+ --ga-border: #e4e7ed;
+ --ga-text: #303133;
+ --ga-muted: #606266;
+ --ga-sidebar-width: 210px;
+ color: var(--ga-text);
+ background: var(--ga-app-bg);
+ font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Microsoft YaHei", Arial, sans-serif;
+}
+
+.go-admin-prototype .go-admin-shell { grid-template-columns: var(--ga-sidebar-width) minmax(0, 1fr); }
+.go-admin-prototype .sidebar-container { width: var(--ga-sidebar-width); padding: 0; background: var(--ga-sidebar); box-shadow: 2px 0 6px rgba(0, 21, 41, .35); transition: width .28s ease, transform .28s ease; }
+.go-admin-prototype .sidebar-logo { height: 64px; min-height: 64px; padding: 0 16px; gap: 12px; color: #fff; text-decoration: none; background: #001529; }
+.go-admin-prototype .brand-mark { width: 34px; height: 34px; flex: 0 0 34px; border-radius: 5px; background: var(--ga-primary); }
+.go-admin-prototype .brand-copy { min-width: 0; }
+.go-admin-prototype .brand-name { white-space: nowrap; }
+.go-admin-prototype .brand-subtitle { color: rgba(255,255,255,.56); white-space: nowrap; }
+.go-admin-prototype .el-menu { gap: 0; padding: 8px 0; }
+.go-admin-prototype .menu-group,
+.go-admin-prototype .el-menu-item { min-height: 50px; height: 50px; padding: 0 18px; border-radius: 0; gap: 14px; color: rgba(255,255,255,.82); }
+.go-admin-prototype .menu-group { display: flex; align-items: center; font-size: 14px; font-weight: 500; }
+.go-admin-prototype .menu-group .menu-arrow { width: 14px; margin-left: auto; transform: rotate(90deg); }
+.go-admin-prototype .el-menu-item:hover { color: #fff; background: var(--ga-sidebar-hover); }
+.go-admin-prototype .el-menu-item.active { color: var(--ga-primary); background: var(--ga-sidebar-hover); box-shadow: inset 3px 0 0 var(--ga-primary); }
+.go-admin-prototype .side-note { margin: 12px; padding: 11px 12px; border-radius: 4px; color: rgba(255,255,255,.72); }
+
+.go-admin-prototype .main-container { min-width: 0; background: var(--ga-app-bg); }
+.go-admin-prototype .fixed-header { position: sticky; top: 0; z-index: 30; }
+.go-admin-prototype .navbar { position: relative; min-height: 50px; height: 50px; padding: 0 16px 0 0; border-bottom: 1px solid #eef0f6; background: #fff; box-shadow: 0 1px 8px rgba(79,70,229,.06); backdrop-filter: none; }
+.go-admin-prototype .navbar::after { content: ""; position: absolute; right: 0; bottom: 0; left: 0; height: 2px; background: linear-gradient(90deg, #1677ff, #40a9ff); opacity: .7; }
+.go-admin-prototype .navbar-action,
+.go-admin-prototype .avatar-button { min-width: 46px; height: 48px; padding: 0 12px; border: 0; display: inline-flex; align-items: center; justify-content: center; gap: 7px; background: transparent; color: #64748b; }
+.go-admin-prototype .navbar-action:hover,
+.go-admin-prototype .avatar-button:hover { color: var(--ga-primary); background: rgba(22,119,255,.06); }
+.go-admin-prototype .navbar-action svg { width: 19px; height: 19px; }
+.go-admin-prototype .mobile-menu { display: none; }
+.go-admin-prototype .breadcrumb { display: flex; align-items: center; gap: 9px; color: #97a8be; font-size: 13px; white-space: nowrap; }
+.go-admin-prototype .breadcrumb a { color: #606266; text-decoration: none; }
+.go-admin-prototype .breadcrumb strong { color: #303133; font-weight: 500; }
+.go-admin-prototype .avatar-button { min-width: auto; }
+.go-admin-prototype .avatar { width: 32px; height: 32px; display: grid; place-items: center; border: 2px solid rgba(22,119,255,.2); border-radius: 50%; color: var(--ga-primary); }
+.go-admin-prototype .prototype-pill { min-height: 25px; border-radius: 4px; }
+
+.go-admin-prototype .tags-view-container { height: 40px; padding: 8px 8px 0; display: flex; align-items: flex-end; gap: 3px; overflow-x: auto; border-bottom: 1px solid #e8eaec; background: #fff; box-shadow: 0 1px 4px rgba(0,21,41,.08); }
+.go-admin-prototype .tags-view-item { height: 32px; padding: 0 10px; border: 1px solid #e0e0e6; border-radius: 3px 3px 0 0; flex: 0 0 auto; background: #f8f9fa; color: #606266; font-size: 12px; }
+.go-admin-prototype .tags-view-item:hover { color: var(--ga-primary); background: #e6f4ff; }
+.go-admin-prototype .tags-view-item.active { color: var(--ga-primary); border-color: #91caff; border-bottom-color: #fff; background: #fff; font-weight: 500; }
+.go-admin-prototype .tags-view-item span { margin-left: 4px; color: #909399; }
+
+.go-admin-prototype .app-main { width: 100%; min-height: calc(100vh - 90px); padding: 16px; background: var(--ga-app-bg); }
+.go-admin-prototype .compact-header { margin-bottom: 14px; }
+.go-admin-prototype .compact-header h1 { font-size: 20px; font-weight: 500; letter-spacing: 0; }
+.go-admin-prototype .compact-header p { font-size: 13px; }
+.go-admin-prototype .el-card { border-color: var(--ga-border); border-radius: 4px; box-shadow: 0 1px 2px rgba(0,0,0,.03); }
+.go-admin-prototype .card-header { min-height: 48px; padding: 10px 14px; }
+.go-admin-prototype .card-body { padding: 14px; }
+.go-admin-prototype .metric { padding: 14px; }
+
+.go-admin-prototype .el-button { min-height: 32px; height: 32px; padding: 5px 12px; border-color: #dcdfe6; border-radius: 4px; background: #fff; color: #606266; font-size: 12px; font-weight: 400; }
+.go-admin-prototype .el-button svg { width: 15px; height: 15px; }
+.go-admin-prototype .el-button:hover { color: var(--ga-primary); border-color: #a0cfff; background: #ecf5ff; }
+.go-admin-prototype .el-button-primary { color: #fff; border-color: var(--ga-primary); background: var(--ga-primary); }
+.go-admin-prototype .el-button-primary:hover { color: #fff; border-color: var(--ga-primary-hover); background: var(--ga-primary-hover); }
+.go-admin-prototype .el-button-link { min-height: 30px; height: 30px; padding: 3px 4px; border: 0; color: var(--ga-primary); background: transparent; }
+.go-admin-prototype .el-button:disabled { color: #a8abb2; border-color: #e4e7ed; background: #f5f7fa; }
+
+.go-admin-prototype .el-form { color: var(--ga-text); }
+.go-admin-prototype .el-form-inline { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px 18px; padding-bottom: 14px; border-bottom: 1px solid #ebeef5; }
+.go-admin-prototype .form-item { min-width: 180px; display: grid; grid-template-columns: auto minmax(150px, 220px); align-items: center; gap: 8px; }
+.go-admin-prototype .form-item label { color: #606266; font-size: 13px; white-space: nowrap; }
+.go-admin-prototype .form-actions { display: flex; gap: 8px; }
+.go-admin-prototype .el-input,
+.go-admin-prototype .el-select { min-height: 32px; height: 32px; padding: 4px 10px; border-color: #dcdfe6; border-radius: 4px; color: #606266; font-size: 13px; }
+.go-admin-prototype .el-input:focus,
+.go-admin-prototype .el-select:focus { border-color: var(--ga-primary); outline: 2px solid rgba(22,119,255,.16); }
+.go-admin-prototype .vertical-form { display: grid; gap: 16px; }
+.go-admin-prototype .vertical-form .form-item { grid-template-columns: 92px minmax(0,1fr); }
+.go-admin-prototype .vertical-form .help { margin: -8px 0 0 100px; }
+.go-admin-prototype .form-footer { display: flex; justify-content: flex-end; }
+
+.go-admin-prototype .operation-bar { min-height: 48px; display: flex; align-items: center; justify-content: space-between; gap: 12px; }
+.go-admin-prototype .operation-actions { display: flex; flex-wrap: wrap; gap: 8px; }
+.go-admin-prototype .permission-hint { display: inline-flex; align-items: center; gap: 5px; color: #909399; font-size: 12px; }
+.go-admin-prototype .permission-hint svg { width: 14px; height: 14px; }
+.go-admin-prototype .el-table { min-width: 760px; border: 1px solid #ebeef5; }
+.go-admin-prototype .el-table th,
+.go-admin-prototype .el-table td { padding: 9px 10px; border-right: 1px solid #ebeef5; border-bottom-color: #ebeef5; }
+.go-admin-prototype .el-table th { background: #f5f7fa; color: #909399; font-weight: 500; }
+.go-admin-prototype .el-table tbody tr:nth-child(even) { background: #fafafa; }
+.go-admin-prototype .el-table tbody tr:hover { background: #f5f7fa; }
+.go-admin-prototype .checkbox-faux { width: 14px; height: 14px; display: inline-block; border: 1px solid #dcdfe6; border-radius: 2px; background: #fff; }
+.go-admin-prototype .action-divider { height: 14px; margin: 0 3px; display: inline-block; border-left: 1px solid #dcdfe6; vertical-align: middle; }
+.go-admin-prototype .el-tag { min-height: 24px; padding: 2px 8px; border: 1px solid currentColor; border-radius: 4px; font-weight: 400; }
+.go-admin-prototype .el-tag::before { display: none; }
+
+.go-admin-prototype .pagination-container { min-height: 48px; display: flex; align-items: center; justify-content: flex-end; gap: 6px; color: #606266; font-size: 12px; }
+.go-admin-prototype .pagination-container button { min-width: 30px; height: 28px; border: 0; border-radius: 3px; background: #f4f4f5; color: #606266; }
+.go-admin-prototype .pagination-container button.active { color: #fff; background: var(--ga-primary); }
+.go-admin-prototype .pagination-container button:disabled { color: #c0c4cc; cursor: not-allowed; }
+.go-admin-prototype .pagination-size { height: 28px; border: 1px solid #dcdfe6; border-radius: 4px; color: #606266; }
+.go-admin-prototype .pagination-total { margin-right: 4px; }
+
+.go-admin-prototype .description-list { display: grid; }
+.go-admin-prototype .description-row { min-height: 43px; padding: 8px 0; display: grid; grid-template-columns: minmax(90px,.7fr) minmax(0,1.5fr) auto; align-items: center; gap: 10px; border-bottom: 1px solid #ebeef5; }
+.go-admin-prototype .description-row:last-child { border-bottom: 0; }
+.go-admin-prototype .description-row > span:first-child { color: #909399; font-size: 12px; }
+.go-admin-prototype .description-row strong { font-size: 13px; font-weight: 500; }
+
+.go-admin-prototype .sense-video-stage,
+.go-admin-prototype .sense-zone-canvas { border-radius: 4px; }
+.go-admin-prototype .el-overlay { background: rgba(0,0,0,.5); }
+.go-admin-prototype .el-dialog { width: min(600px,100%); border-radius: 4px; }
+.go-admin-prototype .el-dialog-header,
+.go-admin-prototype .el-dialog-footer { padding: 16px 20px; }
+.go-admin-prototype .el-dialog-body { padding: 20px; }
+.go-admin-prototype .dialog-close { min-height: 32px; height: 32px; color: #909399; }
+
+.go-admin-prototype .go-admin-shell.compact { grid-template-columns: 54px minmax(0,1fr); }
+.go-admin-prototype .go-admin-shell.compact .sidebar-container { width: 54px; }
+.go-admin-prototype .go-admin-shell.compact .brand-copy,
+.go-admin-prototype .go-admin-shell.compact .el-menu-item span,
+.go-admin-prototype .go-admin-shell.compact .menu-group span,
+.go-admin-prototype .go-admin-shell.compact .menu-arrow,
+.go-admin-prototype .go-admin-shell.compact .side-note { display: none; }
+.go-admin-prototype .go-admin-shell.compact .sidebar-logo,
+.go-admin-prototype .go-admin-shell.compact .menu-group,
+.go-admin-prototype .go-admin-shell.compact .el-menu-item { padding-right: 0; padding-left: 0; justify-content: center; }
+
+@media (max-width: 900px) {
+ .go-admin-prototype .go-admin-shell,
+ .go-admin-prototype .go-admin-shell.compact { display: block; }
+ .go-admin-prototype .sidebar-container,
+ .go-admin-prototype .go-admin-shell.compact .sidebar-container { position: fixed; top: 0; left: 0; z-index: 40; width: min(300px,88vw); height: 100vh; transform: translateX(-102%); }
+ .go-admin-prototype .sidebar-container.open,
+ .go-admin-prototype .go-admin-shell.compact .sidebar-container.open { transform: translateX(0); }
+ .go-admin-prototype .go-admin-shell.compact .brand-copy,
+ .go-admin-prototype .go-admin-shell.compact .el-menu-item span,
+ .go-admin-prototype .go-admin-shell.compact .menu-group span,
+ .go-admin-prototype .go-admin-shell.compact .menu-arrow,
+ .go-admin-prototype .go-admin-shell.compact .side-note { display: initial; }
+ .go-admin-prototype .go-admin-shell.compact .sidebar-logo,
+ .go-admin-prototype .go-admin-shell.compact .menu-group,
+ .go-admin-prototype .go-admin-shell.compact .el-menu-item { padding: 0 18px; justify-content: flex-start; }
+ .go-admin-prototype .desktop-collapse { display: none; }
+ .go-admin-prototype .mobile-menu { display: inline-flex; }
+ .go-admin-prototype .breadcrumb { max-width: 46vw; overflow: hidden; }
+ .go-admin-prototype .breadcrumb a,
+ .go-admin-prototype .breadcrumb span { display: none; }
+ .go-admin-prototype .app-main { padding: 12px; }
+ .go-admin-prototype .tags-view-container { height: 48px; padding-top: 8px; }
+ .go-admin-prototype .tags-view-item { height: 40px; }
+ .go-admin-prototype .el-button { min-height: 44px; height: 44px; }
+ .go-admin-prototype .el-input,
+ .go-admin-prototype .el-select { min-height: 44px; height: 44px; font-size: 16px; }
+ .go-admin-prototype .el-form-inline { align-items: stretch; }
+ .go-admin-prototype .el-form-inline .form-item { width: 100%; grid-template-columns: 82px minmax(0,1fr); }
+ .go-admin-prototype .el-form-inline .form-actions { margin-left: 90px; }
+ .go-admin-prototype .operation-bar { align-items: flex-start; flex-direction: column; padding: 9px 0; }
+ .go-admin-prototype .pagination-container button,
+ .go-admin-prototype .pagination-size { min-width: 40px; height: 40px; }
+}
+
+@media (max-width: 430px) {
+ .go-admin-prototype .desktop-only,
+ .go-admin-prototype .prototype-pill { display: none; }
+ .go-admin-prototype .topbar-actions { gap: 0; }
+ .go-admin-prototype .navbar-action,
+ .go-admin-prototype .avatar-button { min-width: 42px; padding: 0 8px; }
+ .go-admin-prototype .vertical-form .form-item { grid-template-columns: 1fr; gap: 5px; }
+ .go-admin-prototype .vertical-form .help { margin-left: 0; }
+ .go-admin-prototype .pagination-container { justify-content: flex-start; overflow-x: auto; }
+}
+
diff --git a/prototypes/bell/bell.css b/prototypes/bell/bell.css
new file mode 100644
index 0000000..30f5062
--- /dev/null
+++ b/prototypes/bell/bell.css
@@ -0,0 +1,33 @@
+/* Bell-only components layered on the shared go-admin-ui prototype adapter. */
+.bell-go-admin .brand-mark { background: #1677ff; }
+.bell-go-admin .bell-workbench { grid-template-columns: minmax(340px,.95fr) minmax(460px,1.35fr); }
+.bell-go-admin .alert-list { display: grid; gap: 8px; }
+.bell-go-admin .alert-row { width: 100%; min-height: 72px; grid-template-columns: 4px minmax(0,1fr) auto; padding: 11px 12px; border-color: #e4e7ed; border-radius: 4px; text-align: left; color: #303133; }
+.bell-go-admin .alert-row:hover { border-color: #91caff; background: #f5f9ff; }
+.bell-go-admin .alert-row.selected { border-color: #69b1ff; background: #e6f4ff; box-shadow: inset 0 0 0 1px #91caff; }
+.bell-go-admin .severity-bar { background: #f56c6c; }
+.bell-go-admin .severity-bar.medium { background: #e6a23c; }
+.bell-go-admin .alert-title { display: block; font-size: 14px; font-weight: 500; }
+.bell-go-admin .alert-meta { margin-top: 5px; }
+.bell-go-admin .alert-actions { margin-top: 14px; display: flex; justify-content: flex-end; gap: 8px; }
+.bell-go-admin .el-tabs { margin-bottom: 14px; }
+.bell-go-admin .el-tabs button { height: 36px; padding: 0 16px; color: #606266; font-size: 13px; }
+.bell-go-admin .el-tabs button[aria-selected="true"] { color: #1677ff; border-bottom-color: #1677ff; }
+.bell-go-admin .timeline { padding-left: 2px; }
+.bell-go-admin .timeline-item::before { background: #1677ff; box-shadow: 0 0 0 4px #e6f4ff; }
+.bell-go-admin .dev-only-note { margin: 0 0 18px; border-left-color: #e6a23c; border-radius: 4px; }
+
+@media (max-width: 1080px) {
+ .bell-go-admin .bell-workbench { grid-template-columns: 1fr; }
+}
+
+@media (max-width: 900px) {
+ .bell-go-admin .alert-row { min-height: 76px; }
+ .bell-go-admin .alert-actions { flex-wrap: wrap; }
+ .bell-go-admin .alert-actions .el-button { flex: 1 1 150px; }
+}
+
+@media (max-width: 430px) {
+ .bell-go-admin .alert-row { grid-template-columns: 4px minmax(0,1fr); }
+ .bell-go-admin .alert-row .activity-time { grid-column: 2; }
+}
diff --git a/prototypes/bell/index.html b/prototypes/bell/index.html
index 3d33de0..6994def 100644
--- a/prototypes/bell/index.html
+++ b/prototypes/bell/index.html
@@ -3,60 +3,126 @@
-
- YoVision Bell · 当前 MVP 原型
+
+ YoVision Bell · go-admin-ui 对齐原型
+
+
+
-
+
+
跳到主要内容
-
-