Files
yovision/prototypes/sense/index.html
T

139 lines
19 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="YoVision Sense 当前 MVP 交互原型,直接对齐 go-admin-ui 与 Element Plus">
<title>YoVision Sense · go-admin-ui 对齐原型</title>
<link rel="icon" href="data:,">
<link rel="stylesheet" href="../assets/styles.css">
<link rel="stylesheet" href="../assets/go-admin-ui.css">
</head>
<body class="go-admin-prototype sense-go-admin">
<svg class="sr-only" aria-hidden="true">
<symbol id="icon-menu" viewBox="0 0 24 24"><path d="M4 7h16M4 12h16M4 17h16"/></symbol>
<symbol id="icon-grid" viewBox="0 0 24 24"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/></symbol>
<symbol id="icon-camera" viewBox="0 0 24 24"><path d="M15 10l4.5-2.5v9L15 14z"/><rect x="3" y="6" width="12" height="12" rx="2"/></symbol>
<symbol id="icon-monitor" viewBox="0 0 24 24"><rect x="2" y="4" width="20" height="14" rx="2"/><path d="M8 22h8m-4-4v4"/></symbol>
<symbol id="icon-zone" viewBox="0 0 24 24"><path d="M5 4l14 2 2 12-11 3-7-8z"/><circle cx="5" cy="4" r="1"/><circle cx="19" cy="6" r="1"/><circle cx="21" cy="18" r="1"/><circle cx="10" cy="21" r="1"/><circle cx="3" cy="13" r="1"/></symbol>
<symbol id="icon-plus" viewBox="0 0 24 24"><path d="M12 5v14M5 12h14"/></symbol>
<symbol id="icon-search" viewBox="0 0 24 24"><circle cx="11" cy="11" r="7"/><path d="M20 20l-4-4"/></symbol>
<symbol id="icon-refresh" viewBox="0 0 24 24"><path d="M20 6v5h-5M4 18v-5h5M18 9a7 7 0 0 0-12-2L4 11m16 2-2 4a7 7 0 0 1-12-2"/></symbol>
<symbol id="icon-fullscreen" viewBox="0 0 24 24"><path d="M8 3H3v5M16 3h5v5M8 21H3v-5M16 21h5v-5"/></symbol>
<symbol id="icon-user" viewBox="0 0 24 24"><circle cx="12" cy="8" r="4"/><path d="M4 21a8 8 0 0 1 16 0"/></symbol>
<symbol id="icon-lock" viewBox="0 0 24 24"><rect x="5" y="10" width="14" height="11" rx="2"/><path d="M8 10V7a4 4 0 0 1 8 0v3"/></symbol>
<symbol id="icon-arrow" viewBox="0 0 24 24"><path d="M9 18l6-6-6-6"/></symbol>
</svg>
<a class="skip-link" href="#main-content">跳到主要内容</a>
<div class="app-shell go-admin-shell" data-go-admin-shell>
<aside class="sidebar sidebar-container" data-sidebar aria-label="Sense 主导航">
<a class="brand sidebar-logo" href="../index.html">
<span class="brand-mark">S</span>
<span class="brand-copy"><span class="brand-name">YoVision Sense</span><span class="brand-subtitle">智能视频感知平台</span></span>
</a>
<nav class="side-nav el-menu" aria-label="视频感知菜单">
<div class="menu-group"><svg aria-hidden="true"><use href="#icon-camera"></use></svg><span>视频感知</span><svg class="menu-arrow" aria-hidden="true"><use href="#icon-arrow"></use></svg></div>
<button class="active el-menu-item" data-view-target="overview" data-title="运行总览"><svg aria-hidden="true"><use href="#icon-grid"></use></svg><span>运行总览</span></button>
<button class="el-menu-item" data-view-target="devices" data-title="设备接入"><svg aria-hidden="true"><use href="#icon-camera"></use></svg><span>设备接入</span></button>
<button class="el-menu-item" data-view-target="live" data-title="实时监看"><svg aria-hidden="true"><use href="#icon-monitor"></use></svg><span>实时监看</span></button>
<button class="el-menu-item" data-view-target="zones" data-title="区域配置"><svg aria-hidden="true"><use href="#icon-zone"></use></svg><span>区域配置</span></button>
</nav>
<div class="side-note"><strong>独立产品边界</strong><span>Brain、Bell 离线不影响 Sense;摄像头凭据只写不读。</span></div>
</aside>
<div class="main-column main-container">
<div class="fixed-header">
<header class="topbar navbar">
<div class="topbar-left">
<button class="navbar-action mobile-menu" type="button" data-mobile-menu aria-label="打开主导航" aria-expanded="false"><svg aria-hidden="true"><use href="#icon-menu"></use></svg></button>
<button class="navbar-action desktop-collapse" type="button" data-collapse-sidebar aria-label="折叠主导航" aria-expanded="true"><svg aria-hidden="true"><use href="#icon-menu"></use></svg></button>
<nav class="breadcrumb" aria-label="面包屑"><a href="../index.html">YoVision</a><span>/</span><span>Sense</span><span>/</span><strong data-page-name>运行总览</strong></nav>
</div>
<div class="topbar-actions right-menu">
<button class="navbar-action" type="button" data-toast="原型搜索仅演示入口,不发送请求" aria-label="全局搜索"><svg aria-hidden="true"><use href="#icon-search"></use></svg></button>
<button class="navbar-action desktop-only" type="button" data-toast="原型不切换浏览器全屏" aria-label="全屏"><svg aria-hidden="true"><use href="#icon-fullscreen"></use></svg></button>
<span class="prototype-pill">交互原型 · 非生产数据</span>
<button class="avatar-button" type="button" data-toast="当前原型用户:管理员" aria-label="打开用户菜单"><span class="avatar"><svg aria-hidden="true"><use href="#icon-user"></use></svg></span><span class="desktop-only">管理员</span></button>
</div>
</header>
<nav class="tags-view-container" aria-label="已访问页面">
<button class="tags-view-item active" data-view-target="overview" data-title="运行总览" aria-current="page">运行总览</button>
<button class="tags-view-item" data-view-target="devices" data-title="设备接入">设备接入 <span aria-hidden="true">×</span></button>
<button class="tags-view-item" data-view-target="live" data-title="实时监看">实时监看 <span aria-hidden="true">×</span></button>
<button class="tags-view-item" data-view-target="zones" data-title="区域配置">区域配置 <span aria-hidden="true">×</span></button>
</nav>
</div>
<main id="main-content" class="content app-main" tabindex="-1">
<section class="view active" data-view="overview">
<div class="page-header compact-header"><div><h1>运行总览</h1><p>设备、媒体与配置的最小可见状态。Brain、Bell 当前均未连接,不影响 Sense 独立运行。</p></div><div class="page-actions"><button class="btn el-button el-button-primary" data-open-modal="add-device" title="权限:sense:device:add"><svg aria-hidden="true"><use href="#icon-plus"></use></svg>添加设备</button></div></div>
<div class="metric-grid">
<article class="metric el-card"><div class="metric-label">视频设备</div><div class="metric-value">6</div><div class="metric-foot"><strong>5 在线</strong><span>· 1 待激活</span></div></article>
<article class="metric el-card"><div class="metric-label">MediaMTX 路径</div><div class="metric-value">5/5</div><div class="metric-foot"><strong>已收敛</strong><span>· 12 秒前</span></div></article>
<article class="metric el-card"><div class="metric-label">区域版本</div><div class="metric-value">8</div><div class="metric-foot"><strong>7 生效</strong><span>· 1 草稿</span></div></article>
<article class="metric el-card"><div class="metric-label">需要处理</div><div class="metric-value">2</div><div class="metric-foot"><span class="status status-warning el-tag">认证 / 校时</span></div></article>
</div>
<div class="grid grid-2">
<article class="card el-card"><header class="card-header"><div><h2>设备与媒体状态</h2><p class="card-subtitle">期望态与实际态的快速对照</p></div><button class="btn btn-quiet el-button el-button-link" data-view-target="devices">查看设备</button></header><div class="card-body">
<div class="activity-list">
<div class="activity-item"><div class="activity-icon"><svg aria-hidden="true"><use href="#icon-camera"></use></svg></div><div><div class="activity-title">北围墙 01</div><div class="activity-meta">主码流 1080p · MediaMTX reader 1</div></div><span class="status status-success el-tag">在线</span></div>
<div class="activity-item"><div class="activity-icon"><svg aria-hidden="true"><use href="#icon-camera"></use></svg></div><div><div class="activity-title">宿舍东门 02</div><div class="activity-meta">ONVIF 认证失败 · 凭据未回显</div></div><span class="status status-danger el-tag">需处理</span></div>
<div class="activity-item"><div class="activity-icon"><svg aria-hidden="true"><use href="#icon-camera"></use></svg></div><div><div class="activity-title">食堂后门 01</div><div class="activity-meta">已发现 · 等待选择 Profile</div></div><span class="status status-warning el-tag">待激活</span></div>
</div>
</div></article>
<article class="card el-card"><header class="card-header"><div><h2>独立运行状态</h2><p class="card-subtitle">跨项目未连接不构成故障</p></div></header><div class="card-body stack">
<div class="description-row"><span>Sense Core</span><strong>API、数据库、审计可用</strong><span class="status status-success el-tag">正常</span></div>
<div class="description-row"><span>Brain 适配器</span><strong>MVP #8 不要求连接</strong><span class="status status-neutral el-tag">未配置</span></div>
<div class="description-row"><span>Bell Connector</span><strong>后续协同工单实现</strong><span class="status status-neutral el-tag">未安装</span></div>
</div></article>
</div>
</section>
<section class="view" data-view="devices" hidden>
<div class="page-header compact-header"><div><h1>设备接入</h1><p>从发现、验证到激活的单设备闭环;凭据更新后只显示脱敏结果。</p></div></div>
<article class="card el-card box-card"><div class="card-body">
<form class="search-form el-form el-form-inline" data-go-admin-query data-query-input="#device-filter">
<div class="form-item"><label for="device-filter">设备关键字</label><input id="device-filter" class="input el-input" data-filter-input="#device-table" placeholder="名称、地址或状态"></div>
<div class="form-item"><label for="device-status">接入状态</label><select id="device-status" class="input el-select"><option>全部状态</option><option>在线</option><option>需处理</option><option>待激活</option></select></div>
<div class="form-actions"><button class="btn el-button el-button-primary" type="submit"><svg aria-hidden="true"><use href="#icon-search"></use></svg>搜索</button><button class="btn el-button" type="reset" data-reset-device-query><svg aria-hidden="true"><use href="#icon-refresh"></use></svg>重置</button></div>
</form>
<div class="operation-bar">
<div class="operation-actions"><button class="btn el-button el-button-primary" data-open-modal="add-device" title="权限:sense:device:add"><svg aria-hidden="true"><use href="#icon-plus"></use></svg>新增</button><button class="btn el-button" data-toast="已开始发现局域网 ONVIF 设备" title="权限:sense:device:discover"><svg aria-hidden="true"><use href="#icon-search"></use></svg>发现设备</button><button class="btn el-button" disabled title="权限:sense:device:disable;请先选择设备"><svg aria-hidden="true"><use href="#icon-lock"></use></svg>批量停用</button></div>
<span class="permission-hint"><svg aria-hidden="true"><use href="#icon-lock"></use></svg>操作按钮受 RBAC 权限控制</span>
</div>
<div class="table-wrap"><table id="device-table" class="el-table"><thead><tr><th><span class="checkbox-faux" aria-hidden="true"></span><span class="sr-only">选择</span></th><th>设备</th><th>管理地址</th><th>接入状态</th><th>选定 Profile</th><th>操作</th></tr></thead><tbody>
<tr><td><span class="checkbox-faux" aria-hidden="true"></span></td><td><span class="table-title">北围墙 01</span><span class="table-subtitle">video · ONVIF</span></td><td>192.168.10.21</td><td><span class="status status-success el-tag">在线</span></td><td>MainStream · 1080p</td><td><button class="btn btn-quiet el-button-link" data-toast="已打开北围墙 01 详情">查看</button><span class="action-divider"></span><button class="btn btn-quiet el-button-link" data-toast="已打开编辑窗口">修改</button></td></tr>
<tr><td><span class="checkbox-faux" aria-hidden="true"></span></td><td><span class="table-title">宿舍东门 02</span><span class="table-subtitle">video · ONVIF</span></td><td>192.168.10.32</td><td><span class="status status-danger el-tag">认证失败</span></td><td>SubStream · 720p</td><td><button class="btn btn-quiet el-button-link" data-toast="凭据更新窗口只允许写入,不会回显旧密码">更新凭据</button></td></tr>
<tr><td><span class="checkbox-faux" aria-hidden="true"></span></td><td><span class="table-title">食堂后门 01</span><span class="table-subtitle">video · 手工添加</span></td><td>192.168.10.45</td><td><span class="status status-warning el-tag">待激活</span></td><td>尚未选择</td><td><button class="btn btn-quiet el-button-link" data-toast="已开始重新探测 Profile">探测</button></td></tr>
</tbody></table></div>
<nav class="pagination-container el-pagination" aria-label="设备列表分页"><span class="pagination-total">共 3 条</span><button type="button" disabled aria-label="上一页">‹</button><button type="button" class="active" aria-current="page">1</button><button type="button" disabled aria-label="下一页">›</button><select class="pagination-size" aria-label="每页条数"><option>10 条/页</option><option>20 条/页</option></select></nav>
</div></article>
</section>
<section class="view" data-view="live" hidden>
<div class="page-header compact-header"><div><h1>实时监看</h1><p>通用筛选与状态组件复用 Element Plus;视频舞台是 Sense 专用业务组件。</p></div><div class="page-actions"><select class="input el-select" aria-label="选择摄像头"><option>北围墙 01</option><option>宿舍东门 02</option></select><button class="btn el-button" data-toast="已发起重连,当前画面保持显示"><svg aria-hidden="true"><use href="#icon-refresh"></use></svg>重新连接</button></div></div>
<div class="grid grid-2"><article class="card el-card"><header class="card-header"><div><h2>实时画面</h2><p class="card-subtitle">SenseVideoStage · 业务专用组件</p></div><span class="status status-success el-tag">实时</span></header><div class="card-body"><div class="video-stage sense-video-stage" role="img" aria-label="北围墙摄像头的模拟实时画面,画面中显示已配置的危险区域"><div class="camera-caption">北围墙 01 · MainStream</div><div class="zone-shape"></div><span class="zone-label">危险区域 A</span><span class="video-time">2026-08-12 10:18:24 CST</span></div></div></article><article class="card el-card"><header class="card-header"><h2>播放状态</h2></header><div class="card-body description-list"><div class="description-row"><span>协议</span><strong>WebRTC / MediaMTX</strong></div><div class="description-row"><span>源 Profile</span><strong>MainStream · 1920×1080</strong></div><div class="description-row"><span>连接质量</span><strong>1.8 Mbps · 延迟 340 ms</strong></div><div class="description-row"><span>最近重连</span><strong>无 · 已稳定 04:18:32</strong></div></div></article></div>
</section>
<section class="view" data-view="zones" hidden>
<div class="page-header compact-header"><div><h1>区域配置</h1><p>通用表单与按钮复用 Element Plus;区域绘制画布是 Sense 专用业务组件。</p></div><div class="page-actions"><button class="btn el-button" data-toast="方向已反转,草稿尚未发布">反转方向</button><button class="btn el-button el-button-primary" data-toast="区域草稿已保存为 v8,尚未发布" title="权限:sense:zone:edit">保存草稿</button></div></div>
<div class="grid grid-2"><article class="card el-card"><header class="card-header"><div><h2>区域画布</h2><p class="card-subtitle">SenseZoneCanvas · 业务专用组件</p></div></header><div class="card-body"><div class="video-stage sense-zone-canvas" role="img" aria-label="区域编辑画布,包含五边形危险区域"><div class="camera-caption">北围墙 01 · MainStream · 1920×1080</div><div class="zone-shape"></div><span class="zone-label">危险区域 A · 草稿</span></div></div></article><article class="card el-card"><header class="card-header"><h2>区域属性</h2><span class="status status-warning el-tag">草稿 v8</span></header><div class="card-body"><form class="el-form vertical-form"><div class="form-item"><label for="zone-name">区域名称</label><input id="zone-name" class="input el-input" value="危险区域 A"></div><div class="form-item"><label for="zone-rule">区域类型</label><select id="zone-rule" class="input el-select"><option>危险区域</option><option>方向警戒线</option><option>聚集区域</option></select></div><div class="form-item"><label for="zone-profile">绑定 Profile</label><input id="zone-profile" class="input el-input" value="MainStream · 1920×1080" readonly></div><p class="help">坐标按当前 Profile 归一化保存。切换分辨率后,此版本将进入“需重新校准”。</p><div class="form-footer"><button type="button" class="btn el-button el-button-primary" data-toast="区域 v8 已发布,v7 保留用于审计" title="权限:sense:zone:publish">发布区域版本</button></div></form></div></article></div>
</section>
</main>
</div>
</div>
<div class="modal-backdrop el-overlay" id="add-device" aria-hidden="true">
<section class="modal el-dialog" role="dialog" aria-modal="true" aria-labelledby="add-device-title">
<header class="modal-header el-dialog-header"><h2 id="add-device-title">添加视频设备</h2><button class="btn btn-icon btn-quiet dialog-close" data-close-modal aria-label="关闭添加设备窗口">×</button></header>
<div class="modal-body el-dialog-body"><form class="el-form vertical-form"><div class="form-item"><label for="device-name">设备名称</label><input id="device-name" class="input el-input" value="教学楼西门 01"></div><div class="form-item"><label for="device-address">管理地址</label><input id="device-address" class="input el-input" inputmode="url" value="192.168.10.88"></div><div class="form-item"><label for="device-user">ONVIF 用户名</label><input id="device-user" class="input el-input" autocomplete="off" value="operator"></div><div class="form-item"><label for="device-password">密码</label><input id="device-password" class="input el-input" type="password" autocomplete="new-password" placeholder="只写不读,保存后不会回显"><span class="help">原型不会保存输入内容;正式产品中密码不得进入日志或 URL。</span></div></form></div>
<footer class="modal-footer el-dialog-footer"><button class="btn el-button" data-close-modal>取消</button><button class="btn el-button el-button-primary" data-action="add-device">确定</button></footer>
</section>
</div>
<div class="toast-region" data-toast-region aria-live="polite"></div>
<script src="../assets/app.js"></script>
<script src="../assets/go-admin-shell.js"></script>
</body>
</html>