dcdc8d1ddd
全栈知识治理平台首次入库(P1-P10 + 发布链路模拟验证闭环): - 治理核心:源目录/变更集/人工审核/发布批次/发布执行(fail-closed 闸口) - 测试通道:WeKnora 测试 KB 上传/轮询/验收;poll 完成时写入 parser_generation/index_generation,修复 manual/seed 路径发布闸口永久拦截 - 发布适配器 v071(本地 source=测试角色 / 云端 target=生产角色 模拟验证通过): * ES 导出/导入 mapping 自适应(.keyword 子字段、可选 tenant_id) * OSS locator 支持嵌套 scheme;chunks.seq_id 由目标序列分配 * bundle 归档同身份重试原子替换;verifier 按 bundle chunk_type 计数 * 回滚 job payload 支持 prior_execution_id(strict 解码) - 三通道发布+回滚演练实测:publish 4/4 verified,检索命中, rollback 4/4 rolled_back,目标端 PG is_enabled=false、ES is_enabled=false - 前端 A·Data-console 风格全站统一,120 用例通过 - 门禁:go vet / go test 全包通过,gofmt 干净
160 lines
12 KiB
HTML
160 lines
12 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>解析监控 · 方向A 紧凑表格版 [预览稿·模拟数据]</title>
|
||
<style>
|
||
:root{--line:#e5e7eb;--ink:#111827;--sub:#6b7280;--bg:#f7f8fa;--fail:#b91c1c;--ok:#0b6e4f;--warn:#b45309;--run:#1d4ed8}
|
||
*{box-sizing:border-box}
|
||
body{margin:0;background:var(--bg);color:var(--ink);font:14px/1.5 "PingFang SC","Microsoft YaHei",sans-serif}
|
||
header{display:flex;align-items:center;gap:14px;padding:12px 20px;background:#fff;border-bottom:1px solid var(--line)}
|
||
header h1{font-size:17px;margin:0}
|
||
.meta{color:var(--sub);font-size:12px}
|
||
button{font:inherit;padding:5px 12px;border:1px solid var(--line);border-radius:6px;background:#fff;cursor:pointer}
|
||
button.primary{background:#111827;color:#fff;border-color:#111827}
|
||
button.danger{color:var(--fail)}
|
||
.preview-tag{margin-left:auto;background:#fef3c7;color:#92400e;border:1px solid #fcd34d;font-size:12px;padding:2px 10px;border-radius:999px}
|
||
main{max-width:1400px;margin:0 auto;padding:14px 20px;display:flex;flex-direction:column;gap:14px}
|
||
section{background:#fff;border:1px solid var(--line);border-radius:8px}
|
||
.shead{display:flex;align-items:center;gap:10px;padding:10px 14px;border-bottom:1px solid var(--line)}
|
||
.shead h2{font-size:14px;margin:0}
|
||
.shead .spacer{flex:1}
|
||
.counts{display:flex;gap:6px;flex-wrap:wrap}
|
||
.count{font-size:12px;padding:2px 9px;border-radius:999px;border:1px solid var(--line);color:var(--sub)}
|
||
.count b{color:var(--ink)}
|
||
.count.wait b{color:var(--warn)}.count.run b{color:var(--run)}.count.ok b{color:var(--ok)}.count.fail b{color:var(--fail)}
|
||
table{width:100%;border-collapse:collapse;font-size:13px}
|
||
th{color:var(--sub);font-weight:500;text-align:left;font-size:12px;padding:7px 14px;border-bottom:1px solid var(--line);white-space:nowrap}
|
||
td{padding:8px 14px;border-bottom:1px solid #f1f3f6;vertical-align:middle}
|
||
tr:last-child td{border-bottom:none}
|
||
tr.fail-row{background:#fef8f8}
|
||
tr:hover td{background:#fafbfc}
|
||
.badge{font-size:12px;padding:1px 8px;border-radius:4px;border:1px solid var(--line);white-space:nowrap}
|
||
.badge.add{color:var(--ok)}.badge.update,.badge.move{color:var(--run)}.badge.move_scope{color:var(--warn)}.badge.delete{color:var(--fail)}
|
||
.badge.in{background:#eef6ff;border-color:#bfdbfe}.badge.out{background:#f0fdf4;border-color:#bbf7d0}
|
||
.s{font-size:12px;white-space:nowrap}.s.failed{color:var(--fail)}.s.completed{color:var(--ok)}.s.processing{color:var(--run)}.s.pending{color:var(--sub)}.s.stalled{color:var(--warn)}
|
||
code{font:12px ui-monospace,Consolas,monospace;color:var(--sub)}
|
||
.tiny{font-size:12px;color:var(--sub)}
|
||
input[type=text]{font:inherit;padding:5px 8px;border:1px solid var(--line);border-radius:6px;width:120px}
|
||
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:8px 20px;font-size:13px}
|
||
footer{display:flex;gap:0;overflow-x:auto;background:#fff;border:1px solid var(--line);border-radius:8px;font-size:12px}
|
||
footer div{padding:8px 16px;border-right:1px solid var(--line);white-space:nowrap}
|
||
footer div:last-child{border-right:none}
|
||
footer .bad{color:var(--fail)}footer .good{color:var(--ok)}
|
||
#drawer{position:fixed;top:0;right:-420px;width:400px;height:100%;background:#fff;border-left:1px solid var(--line);box-shadow:-4px 0 18px rgba(0,0,0,.06);transition:right .18s;padding:16px;z-index:9;overflow:auto}
|
||
#drawer.open{right:0}
|
||
#drawer h3{margin:0 0 4px;font-size:15px;word-break:break-all}
|
||
#drawer .close{float:right;border:none;background:none;font-size:18px;cursor:pointer;color:var(--sub)}
|
||
.timeline{list-style:none;margin:14px 0;padding:0;border-left:2px solid var(--line)}
|
||
.timeline li{position:relative;padding:0 0 16px 18px;font-size:13px}
|
||
.timeline li::before{content:'';position:absolute;left:-6px;top:4px;width:10px;height:10px;border-radius:50%;background:#fff;border:2px solid var(--sub)}
|
||
.timeline li.done::before{border-color:var(--ok);background:var(--ok)}
|
||
.timeline li.bad::before{border-color:var(--fail);background:var(--fail)}
|
||
.timeline li time{display:block;font-size:12px;color:var(--sub)}
|
||
.err{background:#fef2f2;border:1px solid #fecaca;color:var(--fail);font-size:12px;padding:8px 10px;border-radius:6px;margin:8px 0}
|
||
.dl{display:grid;grid-template-columns:110px 1fr;gap:6px;font-size:13px;margin-top:12px}
|
||
.dl dt{color:var(--sub)}.dl dd{margin:0;word-break:break-all}
|
||
@media(max-width:1024px){.grid2{grid-template-columns:1fr}}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<header>
|
||
<h1>解析监控</h1>
|
||
<span class="meta">快照 2026-09-12 08:00 · 下次自动 08:05</span>
|
||
<span class="meta">活跃 Worker <b>2</b> · 等待 <b style="color:var(--warn)">3</b> · 运行 <b style="color:var(--run)">4</b> · 失败 <b style="color:var(--fail)">2</b></span>
|
||
<button class="spacer" style="margin-left:auto">刷新</button>
|
||
<span class="preview-tag">预览稿 · 模拟数据 · 方向A</span>
|
||
</header>
|
||
<main>
|
||
|
||
<section>
|
||
<div class="shead"><h2>快照差异 → 解析队列 → 死信 → 资源(单页主线,表格为主)</h2>
|
||
<div class="counts spacer">
|
||
<span class="count wait">待确认 <b>3</b></span><span class="count run">处理中 <b>4</b></span>
|
||
<span class="count ok">成功 <b>4530</b></span><span class="count fail">失败 <b>2</b></span>
|
||
</div>
|
||
<label class="tiny">筛选
|
||
<select><option>对内+对外</option><option>对内</option><option>对外</option></select>
|
||
</label>
|
||
</div>
|
||
</section>
|
||
|
||
<section>
|
||
<div class="shead"><h2>1 · 快照差异(待确认置顶)</h2><span class="tiny">国内工业 · from 09-08 → to 09-12</span><span class="spacer"></span><span class="tiny">操作人</span><input type="text" value="姚工"></div>
|
||
<table>
|
||
<thead><tr><th style="width:34px"><input type="checkbox" checked></th><th>变更</th><th>文件</th><th>路径(旧 → 新)</th><th>目标</th><th>证据</th><th style="width:110px">操作</th></tr></thead>
|
||
<tbody>
|
||
<tr><td><input type="checkbox" checked></td><td><span class="badge add">新增</span></td><td><a href="#" onclick="openDrawer('CR20B用户手册V2.pdf');return false">CR20B用户手册V2.pdf</a></td><td class="tiny">— → 01|产品资料/CR20B/</td><td><span class="badge in">对内</span></td><td class="tiny">内容Hash 8e3f…(来源提供)</td><td><button class="primary" style="font-size:12px">确认处理</button></td></tr>
|
||
<tr><td><input type="checkbox" checked></td><td><span class="badge update">更新</span></td><td><a href="#" onclick="openDrawer('DobotStudio固件说明.docx');return false">DobotStudio固件说明.docx</a></td><td class="tiny">同一文件,版本 r12 → r13</td><td><span class="badge in">对内</span><span class="badge out">对外</span></td><td class="tiny">内容Hash变化(真更新)</td><td><button class="primary" style="font-size:12px">确认处理</button></td></tr>
|
||
<tr><td><input type="checkbox" checked></td><td><span class="badge move_scope">范围变化</span></td><td><a href="#" onclick="openDrawer('越疆售后FAQ.xlsx');return false">越疆售后FAQ.xlsx</a></td><td class="tiny">对内 → 对内+对外</td><td><span class="badge out">对外</span></td><td class="tiny">Hash未变,仅标注</td><td><button class="primary" style="font-size:12px">确认处理</button></td></tr>
|
||
<tr><td>—</td><td><span class="badge move">移动</span></td><td>安装指南.pdf</td><td class="tiny">01|产品资料/ → 快速入门/安装指南.pdf</td><td><span class="badge in">对内</span></td><td class="tiny">同名同Hash → 自动改名,不重解析</td><td class="tiny">已自动处理</td></tr>
|
||
<tr class="fail-row"><td>—</td><td><span class="badge delete">删除</span></td><td>旧手册.pdf</td><td class="tiny">02|已下架资料/旧手册.pdf →</td><td>—</td><td class="tiny">来源缺失</td><td class="tiny">等待移除确认</td></tr>
|
||
</tbody>
|
||
</table>
|
||
</section>
|
||
|
||
<section>
|
||
<div class="shead"><h2>2 · 解析队列(失败/停滞置顶)</h2><span class="tiny">共 4536 · 1小时:成功 88.9% · p95 30分钟</span><span class="spacer"></span><input type="text" value="姚工"><button class="danger">批量重试(2)</button></div>
|
||
<table>
|
||
<thead><tr><th style="width:34px"></th><th>状态</th><th>阶段链</th><th>文件</th><th>目标</th><th>错误码</th><th>已停留</th><th>重试</th></tr></thead>
|
||
<tbody>
|
||
<tr class="fail-row"><td><input type="checkbox" checked></td><td class="s failed">失败</td><td class="tiny">✓✓✓✗···· <b style="color:var(--fail)">文档解析</b></td><td><a href="#" onclick="openDrawer('CR20A.pdf');return false">CR20A.pdf</a></td><td><span class="badge out">对外</span></td><td><code>validation_failed</code></td><td>—</td><td>1</td></tr>
|
||
<tr class="fail-row"><td><input type="checkbox" checked></td><td class="s failed">失败</td><td class="tiny">✓✓✓✓✓✗· <b style="color:var(--fail)">索引增强</b></td><td><a href="#" onclick="openDrawer('MG400碰撞检测.mp4笔记.pdf');return false">MG400碰撞检测笔记.pdf</a></td><td><span class="badge in">对内</span></td><td><code>remote_permanent</code></td><td>—</td><td>5/5 耗尽 · 死信</td></tr>
|
||
<tr><td>—</td><td class="s processing">解析中</td><td class="tiny">✓✓✓✗···· 文档解析</td><td>XVision标定手册.pdf</td><td><span class="badge in">对内</span></td><td>—</td><td>6分钟</td><td>0</td></tr>
|
||
<tr><td>—</td><td class="s pending">等待</td><td class="tiny">等待接单</td><td>NeoSs常见问题.docx</td><td><span class="badge out">对外</span></td><td>—</td><td>2分钟</td><td>0</td></tr>
|
||
<tr><td>—</td><td class="s completed">成功</td><td class="tiny">✓✓✓✓✓✓✓ 完成</td><td>CR5说明书V3.pdf</td><td><span class="badge in">对内</span></td><td>—</td><td>完成</td><td>2</td></tr>
|
||
</tbody>
|
||
</table>
|
||
</section>
|
||
|
||
<section>
|
||
<div class="shead"><h2>3 · 失败队列 DLQ(2条开放死信)</h2><span class="tiny">仅投影;原始任务与审计不可变。重试=新尝试</span></div>
|
||
<table>
|
||
<thead><tr><th>错误码</th><th>类型</th><th>文件</th><th>尝试</th><th>进入死信</th><th></th></tr></thead>
|
||
<tbody>
|
||
<tr><td><code>remote_permanent</code></td><td>上传解析</td><td>MG400碰撞检测笔记.pdf</td><td>5/5</td><td class="tiny">09-11 21:04</td><td><button>重试</button></td></tr>
|
||
<tr><td><code>artifact_invalid</code></td><td>上传解析</td><td>测试固件包.zip.bin</td><td>1/1</td><td class="tiny">09-12 02:11</td><td class="tiny">文件校验永久失败,需来源修复</td></tr>
|
||
</tbody>
|
||
</table>
|
||
</section>
|
||
|
||
<footer>
|
||
<div>10s <b class="good">100%</b></div>
|
||
<div>1小时 · 成功 <b class="good">88.9%</b> 失败 11.1%</div>
|
||
<div>24小时 · 成功 <b class="good">96.4%</b></div>
|
||
<div>耗时 p50 30秒 · p95 30分钟 · 均值 6.9分钟</div>
|
||
<div>CPU <b>42%</b> 内存 18.6/32GB</div>
|
||
<div>WeKnora <b class="good">可达</b></div>
|
||
<div>MinerU <b class="bad">容量已满(429)</b></div>
|
||
<div>PostgreSQL <b class="good">可接单</b></div>
|
||
</footer>
|
||
</main>
|
||
|
||
<div id="drawer">
|
||
<button class="close" onclick="document.getElementById('drawer').classList.remove('open')">✕</button>
|
||
<h3 id="drawer-title">CR20A.pdf</h3>
|
||
<p class="tiny">对内+对外 · kb-external · 版本 r7 · 发布 tp-8841</p>
|
||
<div class="err">validation_failed:解析服务返回 422,切片数量=0。建议:确认 MinerU 接单容量后批量重试。</div>
|
||
<ul class="timeline">
|
||
<li class="done">下载完成<time>08:01:02 · 3.2MB</time></li>
|
||
<li class="done">内容Hash校验 8e3f…d41a<time>08:01:04</time></li>
|
||
<li class="done">上传 WeKnora<time>08:01:07 · 成功</time></li>
|
||
<li class="bad">文档解析<time>08:03:40 · 失败(validation_failed)</time></li>
|
||
<li>索引与增强(未执行)</li>
|
||
</ul>
|
||
<dl class="dl">
|
||
<dt>内容Hash</dt><dd>8e3f19…d41a(来源提供)</dd>
|
||
<dt>文件身份</dt><dd>来源稳定ID ext-9931 · 置信度 official_id</dd>
|
||
<dt>最近尝试</dt><dd>job-3f9a… · 第2次 · 164秒</dd>
|
||
<dt>死信</dt><dd>否(仍可重试)</dd>
|
||
</dl>
|
||
<p style="margin-top:16px"><button class="danger" style="width:100%">重试该文件</button></p>
|
||
</div>
|
||
|
||
<script>
|
||
function openDrawer(name){document.getElementById('drawer-title').textContent=name;document.getElementById('drawer').classList.add('open')}
|
||
</script>
|
||
</body>
|
||
</html>
|