diff --git a/prototypes/README.md b/prototypes/README.md index d2e9223..7f5604c 100644 --- a/prototypes/README.md +++ b/prototypes/README.md @@ -14,7 +14,7 @@ python -m http.server 4173 --directory prototypes ## 原型范围 -- `sense/index.html`:设备接入、ONVIF/RTSP、MediaMTX、实时监看和区域配置。 +- `sense/index.html`:设备接入、ONVIF/RTSP、MediaMTX、实时监看和区域配置;直接映射 go-admin-ui 与 Element Plus 的通用管理端组件。 - `brain/index.html`:合成输入到项目内匿名事件的内部流水线;Brain 无客户管理 UI。 - `bell/index.html`:合成事件、不可变 Event、规则/Alert、ack/close 和审计时间线。 - `assets/`:三套原型复用的样式和交互脚本。 @@ -28,6 +28,15 @@ python -m http.server 4173 --directory prototypes - Bell 可注入合成事件,并演示 Alert 的 ack 和 close。 - 所有弹窗支持 `Esc` 关闭,交互元素支持键盘焦点。 +## Sense 的 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 内没有等价组件。 +- 原型仍是无构建依赖的 HTML/CSS/JavaScript,并未嵌入或复制 go-admin-ui / Element Plus 源码;这些名称用于约束正式 Vue 实现的组件落点。 + ## 事实来源边界 - 产品范围以 Gitea Wiki 的 Product Requirements、Product Roadmap 和对应工单为准。 diff --git a/prototypes/sense/go-admin-ui.css b/prototypes/sense/go-admin-ui.css new file mode 100644 index 0000000..aba4ec2 --- /dev/null +++ b/prototypes/sense/go-admin-ui.css @@ -0,0 +1,181 @@ +/* + * Sense 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. + */ +.sense-go-admin { + --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; +} + +.sense-go-admin .go-admin-shell { grid-template-columns: var(--ga-sidebar-width) minmax(0, 1fr); } +.sense-go-admin .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; } +.sense-go-admin .sidebar-logo { height: 64px; min-height: 64px; padding: 0 16px; gap: 12px; color: #fff; text-decoration: none; background: #001529; } +.sense-go-admin .brand-mark { width: 34px; height: 34px; flex: 0 0 34px; border-radius: 5px; background: var(--ga-primary); } +.sense-go-admin .brand-copy { min-width: 0; } +.sense-go-admin .brand-name { white-space: nowrap; } +.sense-go-admin .brand-subtitle { color: rgba(255,255,255,.56); white-space: nowrap; } +.sense-go-admin .el-menu { gap: 0; padding: 8px 0; } +.sense-go-admin .menu-group, +.sense-go-admin .el-menu-item { min-height: 50px; height: 50px; padding: 0 18px; border-radius: 0; gap: 14px; color: rgba(255,255,255,.82); } +.sense-go-admin .menu-group { display: flex; align-items: center; font-size: 14px; font-weight: 500; } +.sense-go-admin .menu-group .menu-arrow { width: 14px; margin-left: auto; transform: rotate(90deg); } +.sense-go-admin .el-menu-item:hover { color: #fff; background: var(--ga-sidebar-hover); } +.sense-go-admin .el-menu-item.active { color: var(--ga-primary); background: var(--ga-sidebar-hover); box-shadow: inset 3px 0 0 var(--ga-primary); } +.sense-go-admin .side-note { margin: 12px; padding: 11px 12px; border-radius: 4px; color: rgba(255,255,255,.72); } + +.sense-go-admin .main-container { min-width: 0; background: var(--ga-app-bg); } +.sense-go-admin .fixed-header { position: sticky; top: 0; z-index: 30; } +.sense-go-admin .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; } +.sense-go-admin .navbar::after { content: ""; position: absolute; right: 0; bottom: 0; left: 0; height: 2px; background: linear-gradient(90deg, #1677ff, #40a9ff); opacity: .7; } +.sense-go-admin .navbar-action, +.sense-go-admin .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; } +.sense-go-admin .navbar-action:hover, +.sense-go-admin .avatar-button:hover { color: var(--ga-primary); background: rgba(22,119,255,.06); } +.sense-go-admin .navbar-action svg { width: 19px; height: 19px; } +.sense-go-admin .mobile-menu { display: none; } +.sense-go-admin .breadcrumb { display: flex; align-items: center; gap: 9px; color: #97a8be; font-size: 13px; white-space: nowrap; } +.sense-go-admin .breadcrumb a { color: #606266; text-decoration: none; } +.sense-go-admin .breadcrumb strong { color: #303133; font-weight: 500; } +.sense-go-admin .avatar-button { min-width: auto; } +.sense-go-admin .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); } +.sense-go-admin .prototype-pill { min-height: 25px; border-radius: 4px; } + +.sense-go-admin .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); } +.sense-go-admin .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; } +.sense-go-admin .tags-view-item:hover { color: var(--ga-primary); background: #e6f4ff; } +.sense-go-admin .tags-view-item.active { color: var(--ga-primary); border-color: #91caff; border-bottom-color: #fff; background: #fff; font-weight: 500; } +.sense-go-admin .tags-view-item span { margin-left: 4px; color: #909399; } + +.sense-go-admin .app-main { width: 100%; min-height: calc(100vh - 90px); padding: 16px; background: var(--ga-app-bg); } +.sense-go-admin .compact-header { margin-bottom: 14px; } +.sense-go-admin .compact-header h1 { font-size: 20px; font-weight: 500; letter-spacing: 0; } +.sense-go-admin .compact-header p { font-size: 13px; } +.sense-go-admin .el-card { border-color: var(--ga-border); border-radius: 4px; box-shadow: 0 1px 2px rgba(0,0,0,.03); } +.sense-go-admin .card-header { min-height: 48px; padding: 10px 14px; } +.sense-go-admin .card-body { padding: 14px; } +.sense-go-admin .metric { padding: 14px; } + +.sense-go-admin .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; } +.sense-go-admin .el-button svg { width: 15px; height: 15px; } +.sense-go-admin .el-button:hover { color: var(--ga-primary); border-color: #a0cfff; background: #ecf5ff; } +.sense-go-admin .el-button-primary { color: #fff; border-color: var(--ga-primary); background: var(--ga-primary); } +.sense-go-admin .el-button-primary:hover { color: #fff; border-color: var(--ga-primary-hover); background: var(--ga-primary-hover); } +.sense-go-admin .el-button-link { min-height: 30px; height: 30px; padding: 3px 4px; border: 0; color: var(--ga-primary); background: transparent; } +.sense-go-admin .el-button:disabled { color: #a8abb2; border-color: #e4e7ed; background: #f5f7fa; } + +.sense-go-admin .el-form { color: var(--ga-text); } +.sense-go-admin .el-form-inline { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px 18px; padding-bottom: 14px; border-bottom: 1px solid #ebeef5; } +.sense-go-admin .form-item { min-width: 180px; display: grid; grid-template-columns: auto minmax(150px, 220px); align-items: center; gap: 8px; } +.sense-go-admin .form-item label { color: #606266; font-size: 13px; white-space: nowrap; } +.sense-go-admin .form-actions { display: flex; gap: 8px; } +.sense-go-admin .el-input, +.sense-go-admin .el-select { min-height: 32px; height: 32px; padding: 4px 10px; border-color: #dcdfe6; border-radius: 4px; color: #606266; font-size: 13px; } +.sense-go-admin .el-input:focus, +.sense-go-admin .el-select:focus { border-color: var(--ga-primary); outline: 2px solid rgba(22,119,255,.16); } +.sense-go-admin .vertical-form { display: grid; gap: 16px; } +.sense-go-admin .vertical-form .form-item { grid-template-columns: 92px minmax(0,1fr); } +.sense-go-admin .vertical-form .help { margin: -8px 0 0 100px; } +.sense-go-admin .form-footer { display: flex; justify-content: flex-end; } + +.sense-go-admin .operation-bar { min-height: 48px; display: flex; align-items: center; justify-content: space-between; gap: 12px; } +.sense-go-admin .operation-actions { display: flex; flex-wrap: wrap; gap: 8px; } +.sense-go-admin .permission-hint { display: inline-flex; align-items: center; gap: 5px; color: #909399; font-size: 12px; } +.sense-go-admin .permission-hint svg { width: 14px; height: 14px; } +.sense-go-admin .el-table { min-width: 760px; border: 1px solid #ebeef5; } +.sense-go-admin .el-table th, +.sense-go-admin .el-table td { padding: 9px 10px; border-right: 1px solid #ebeef5; border-bottom-color: #ebeef5; } +.sense-go-admin .el-table th { background: #f5f7fa; color: #909399; font-weight: 500; } +.sense-go-admin .el-table tbody tr:nth-child(even) { background: #fafafa; } +.sense-go-admin .el-table tbody tr:hover { background: #f5f7fa; } +.sense-go-admin .checkbox-faux { width: 14px; height: 14px; display: inline-block; border: 1px solid #dcdfe6; border-radius: 2px; background: #fff; } +.sense-go-admin .action-divider { height: 14px; margin: 0 3px; display: inline-block; border-left: 1px solid #dcdfe6; vertical-align: middle; } +.sense-go-admin .el-tag { min-height: 24px; padding: 2px 8px; border: 1px solid currentColor; border-radius: 4px; font-weight: 400; } +.sense-go-admin .el-tag::before { display: none; } + +.sense-go-admin .pagination-container { min-height: 48px; display: flex; align-items: center; justify-content: flex-end; gap: 6px; color: #606266; font-size: 12px; } +.sense-go-admin .pagination-container button { min-width: 30px; height: 28px; border: 0; border-radius: 3px; background: #f4f4f5; color: #606266; } +.sense-go-admin .pagination-container button.active { color: #fff; background: var(--ga-primary); } +.sense-go-admin .pagination-container button:disabled { color: #c0c4cc; cursor: not-allowed; } +.sense-go-admin .pagination-size { height: 28px; border: 1px solid #dcdfe6; border-radius: 4px; color: #606266; } +.sense-go-admin .pagination-total { margin-right: 4px; } + +.sense-go-admin .description-list { display: grid; } +.sense-go-admin .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; } +.sense-go-admin .description-row:last-child { border-bottom: 0; } +.sense-go-admin .description-row > span:first-child { color: #909399; font-size: 12px; } +.sense-go-admin .description-row strong { font-size: 13px; font-weight: 500; } + +.sense-go-admin .sense-video-stage, +.sense-go-admin .sense-zone-canvas { border-radius: 4px; } +.sense-go-admin .el-overlay { background: rgba(0,0,0,.5); } +.sense-go-admin .el-dialog { width: min(600px,100%); border-radius: 4px; } +.sense-go-admin .el-dialog-header, +.sense-go-admin .el-dialog-footer { padding: 16px 20px; } +.sense-go-admin .el-dialog-body { padding: 20px; } +.sense-go-admin .dialog-close { min-height: 32px; height: 32px; color: #909399; } + +.sense-go-admin .go-admin-shell.compact { grid-template-columns: 54px minmax(0,1fr); } +.sense-go-admin .go-admin-shell.compact .sidebar-container { width: 54px; } +.sense-go-admin .go-admin-shell.compact .brand-copy, +.sense-go-admin .go-admin-shell.compact .el-menu-item span, +.sense-go-admin .go-admin-shell.compact .menu-group span, +.sense-go-admin .go-admin-shell.compact .menu-arrow, +.sense-go-admin .go-admin-shell.compact .side-note { display: none; } +.sense-go-admin .go-admin-shell.compact .sidebar-logo, +.sense-go-admin .go-admin-shell.compact .menu-group, +.sense-go-admin .go-admin-shell.compact .el-menu-item { padding-right: 0; padding-left: 0; justify-content: center; } + +@media (max-width: 900px) { + .sense-go-admin .go-admin-shell, + .sense-go-admin .go-admin-shell.compact { display: block; } + .sense-go-admin .sidebar-container, + .sense-go-admin .go-admin-shell.compact .sidebar-container { position: fixed; top: 0; left: 0; z-index: 40; width: min(300px,88vw); height: 100vh; transform: translateX(-102%); } + .sense-go-admin .sidebar-container.open, + .sense-go-admin .go-admin-shell.compact .sidebar-container.open { transform: translateX(0); } + .sense-go-admin .go-admin-shell.compact .brand-copy, + .sense-go-admin .go-admin-shell.compact .el-menu-item span, + .sense-go-admin .go-admin-shell.compact .menu-group span, + .sense-go-admin .go-admin-shell.compact .menu-arrow, + .sense-go-admin .go-admin-shell.compact .side-note { display: initial; } + .sense-go-admin .go-admin-shell.compact .sidebar-logo, + .sense-go-admin .go-admin-shell.compact .menu-group, + .sense-go-admin .go-admin-shell.compact .el-menu-item { padding: 0 18px; justify-content: flex-start; } + .sense-go-admin .desktop-collapse { display: none; } + .sense-go-admin .mobile-menu { display: inline-flex; } + .sense-go-admin .breadcrumb { max-width: 46vw; overflow: hidden; } + .sense-go-admin .breadcrumb a, + .sense-go-admin .breadcrumb span { display: none; } + .sense-go-admin .app-main { padding: 12px; } + .sense-go-admin .tags-view-container { height: 48px; padding-top: 8px; } + .sense-go-admin .tags-view-item { height: 40px; } + .sense-go-admin .el-button { min-height: 44px; height: 44px; } + .sense-go-admin .el-input, + .sense-go-admin .el-select { min-height: 44px; height: 44px; font-size: 16px; } + .sense-go-admin .el-form-inline { align-items: stretch; } + .sense-go-admin .el-form-inline .form-item { width: 100%; grid-template-columns: 82px minmax(0,1fr); } + .sense-go-admin .el-form-inline .form-actions { margin-left: 90px; } + .sense-go-admin .operation-bar { align-items: flex-start; flex-direction: column; padding: 9px 0; } + .sense-go-admin .pagination-container button, + .sense-go-admin .pagination-size { min-width: 40px; height: 40px; } +} + +@media (max-width: 430px) { + .sense-go-admin .desktop-only, + .sense-go-admin .prototype-pill { display: none; } + .sense-go-admin .topbar-actions { gap: 0; } + .sense-go-admin .navbar-action, + .sense-go-admin .avatar-button { min-width: 42px; padding: 0 8px; } + .sense-go-admin .vertical-form .form-item { grid-template-columns: 1fr; gap: 5px; } + .sense-go-admin .vertical-form .help { margin-left: 0; } + .sense-go-admin .pagination-container { justify-content: flex-start; overflow-x: auto; } +} diff --git a/prototypes/sense/index.html b/prototypes/sense/index.html index 2e3035c..c45a039 100644 --- a/prototypes/sense/index.html +++ b/prototypes/sense/index.html @@ -3,11 +3,13 @@
- -