- web/index.html 重写为 SPA 外壳:Sider/顶栏常驻,模块页在 #module-frame iframe 内容区加载,点菜单只换 iframe 地址, 彻底消灭整页刷新与白闪(此前只是铺底色缓解) - 新增 shared/shell.js:IAOP_SHELL.navigate() 导航、外壳 hash (#/admin/#models) 与 iframe 地址双向同步、登录守卫、移动端 模块新标签打开;iframe 地址用 location.replace 避免污染 joint history;250ms 轮询回同步(replace 不触发 load 事件); 导航时乐观高亮(后台标签轮询被节流不能作为唯一途径); 前进/后退若恢复了 iframe 旧地址则以外壳 hash 为准强制对齐 - pro-header.js 三模式:外壳(菜单点击走 IAOP_SHELL、导出 IAOP_PRO.setActive)/被嵌(iframe 内,隐藏页内跨页链接与重复 用户标识、保留 Tab-hash 联动)/独立(原行为);菜单渲染后派发 pro:menu-rendered 事件消除导航先于渲染的高亮竞态 - session.js:logout/守卫重定向作用于顶层窗口(iframe 内不再 只跳 iframe 自己) - 修复 iframe 替换元素宽高 bug:fixed 时左右定位不拉伸(回退 固有 300x150),改显式 calc 宽高 - 登录页 next 默认回外壳 ../index.html 实测(本地 http.server + WebBridge 真实浏览器):菜单切换/ 子菜单切换/前进/后退/直达链接(#/admin/#models) URL、iframe、 菜单高亮、子菜单高亮全链路一致,Sider 节点全程不重建; 登录守卫 logout→顶层跳登录、登录后回外壳默认驾驶舱。
132 lines
5.7 KiB
HTML
132 lines
5.7 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<!-- 首屏防闪(issue #131):跨页跳转时外部 CSS 未到的瞬间,
|
||
先用与最终布局一致的底色铺满画布(左 Sider 深色 + 内容区灰),
|
||
消除深色 Sider 区域的白闪(FOUC)。 -->
|
||
<style>html{background:#f0f2f5}@media (min-width:721px){html{background:linear-gradient(90deg,#001529 208px,#f0f2f5 208px)}}</style>
|
||
<!-- 被 SPA 外壳 iframe 嵌入时内容区无 Sider,立即改回纯灰底(首帧前生效) -->
|
||
<script>if(window!==window.top){document.documentElement.style.background="#f0f2f5"}</script>
|
||
<title>iAOP 管理控制台</title>
|
||
<link rel="stylesheet" href="admin.css">
|
||
<link rel="stylesheet" href="../shared/pro.css">
|
||
</head>
|
||
<body data-pro-title="管理控制台">
|
||
<!-- iAOP 管理功能界面(issue #135 / PRD 8.1/8.2)
|
||
纯静态单页(无构建链):模型管理 / 知识库管理 / 告警确认 / 审计查询。
|
||
语义对齐后端内核:template_registry(dev/staging/prod 逐级 promote + 回滚)、
|
||
rag-kb 文档资产、PRD 8.1 告警状态机(待处理→已确认→已闭环)、_log 审计。 -->
|
||
<header id="topbar">
|
||
<h1>iAOP 管理控制台 <span class="sub">模型 / 知识库 / 告警 / 审计</span></h1>
|
||
<div id="topbar-right">
|
||
<span id="who" class="hint"></span>
|
||
<a href="../cockpit/index.html">驾驶舱</a>
|
||
<a href="../studio/index.html">配置台</a>
|
||
</div>
|
||
</header>
|
||
|
||
<nav id="tabs">
|
||
<button class="tab active" data-page="models">模型管理</button>
|
||
<button class="tab" data-page="kb">知识库管理</button>
|
||
<button class="tab" data-page="alerts">告警确认</button>
|
||
<button class="tab" data-page="audit">审计查询</button>
|
||
</nav>
|
||
|
||
<!-- ======================= 模型管理 ======================= -->
|
||
<section class="page active" id="page-models">
|
||
<div class="panel">
|
||
<h2>模型模板列表(阶段:dev → staging → prod,对齐 template_registry)</h2>
|
||
<div class="row">
|
||
<input id="model-name" placeholder="模型名,如 quality_forecast">
|
||
<input id="model-version" placeholder="初始版本,如 1.0.0">
|
||
<button id="btn-register" class="primary">注册新版本</button>
|
||
<span class="hint">语义对齐 core/model-framework/template_registry.py:promote 逐级提升、rollback 回退、全程审计</span>
|
||
</div>
|
||
<table>
|
||
<thead><tr><th>模型</th><th>版本</th><th>阶段</th><th>作者</th><th>更新时间</th><th>操作</th></tr></thead>
|
||
<tbody id="model-tbody"></tbody>
|
||
</table>
|
||
<!-- issue #153:按模型过滤的审计历史(验收:promote/rollback 可追溯) -->
|
||
<div id="model-history" class="detail" hidden></div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ======================= 知识库管理 ======================= -->
|
||
<section class="page" id="page-kb">
|
||
<div class="panel">
|
||
<h2>知识库文档(来源:templates/*/rag-kb/documents,经 build_citations 索引)</h2>
|
||
<div class="row">
|
||
<input type="file" id="kb-file" accept=".md,.txt">
|
||
<button id="btn-kb-upload" class="primary">上传并索引</button>
|
||
<span id="kb-hint" class="hint"></span>
|
||
</div>
|
||
<table>
|
||
<thead><tr><th>文档</th><th>来源</th><th>章节数</th><th>索引状态</th><th>操作</th></tr></thead>
|
||
<tbody id="kb-tbody"></tbody>
|
||
</table>
|
||
<div id="kb-detail" class="detail" hidden></div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ======================= 告警确认 ======================= -->
|
||
<section class="page" id="page-alerts">
|
||
<div class="split-alerts">
|
||
<div class="panel">
|
||
<h2>告警列表(状态机:待处理 → 已确认 → 已闭环,PRD 8.1)</h2>
|
||
<div class="row">
|
||
<select id="alert-filter">
|
||
<option value="">全部状态</option>
|
||
<option value="pending">待处理</option>
|
||
<option value="acked">已确认</option>
|
||
<option value="closed">已闭环</option>
|
||
</select>
|
||
<span class="hint">severity 配色来自 alarm_panel.ti.yaml(P0 红 / P1 黄 / P2 蓝)</span>
|
||
</div>
|
||
<div id="alert-list"></div>
|
||
</div>
|
||
<div class="panel" id="alert-detail-panel">
|
||
<h2>告警详情(LLM 解释 + SOP)</h2>
|
||
<div id="alert-detail"><p class="hint">选择左侧告警查看详情</p></div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ======================= 审计查询 ======================= -->
|
||
<section class="page" id="page-audit">
|
||
<div class="panel">
|
||
<h2>操作审计日志</h2>
|
||
<div class="row">
|
||
<input id="audit-q" placeholder="关键词(操作者/资源/原因)">
|
||
<input id="audit-from" type="date" title="起始日期">
|
||
<input id="audit-to" type="date" title="截止日期">
|
||
<select id="audit-action">
|
||
<option value="">全部动作</option>
|
||
<option value="create">create</option>
|
||
<option value="update">update</option>
|
||
<option value="delete">delete</option>
|
||
<option value="publish">publish</option>
|
||
<option value="rollback">rollback</option>
|
||
<option value="promote">promote</option>
|
||
<option value="ack">ack</option>
|
||
<option value="close">close</option>
|
||
<option value="login">login</option>
|
||
</select>
|
||
<button id="btn-audit-filter">筛选</button>
|
||
<button id="btn-audit-export" class="primary">导出 JSON</button>
|
||
</div>
|
||
<table>
|
||
<thead><tr><th>时间</th><th>操作者</th><th>动作</th><th>资源</th><th>结果/原因</th></tr></thead>
|
||
<tbody id="audit-tbody"></tbody>
|
||
</table>
|
||
</div>
|
||
</section>
|
||
|
||
<script src="../auth/user_store.js"></script>
|
||
<script src="../shared/session.js"></script>
|
||
<script src="../shared/pro-header.js"></script>
|
||
<script src="admin.js"></script>
|
||
</body>
|
||
</html>
|