facc04aa65
本提交为 .git 对象库损坏后的重建提交,内容等价于原先三个本地提交 (5e2fd4c2 / 57a53c98 / 5d7e1873)的累积结果,未做任何额外改动。 一、docs 结构整改(整改 #14) 根因:重构时新结构为 untracked 文件,执行 git stash(未带 -u)未纳入, 随后 git reset 拉回 HEAD 旧 tracked 树,导致旧树复活、新旧两棵目录 树并存于 docs/,共 791 文件、双分类体系冲突。 修复动作: - b2 同名异主题文件改名迁移保全 9 个 - C 类 39 个孤立文件按主题正确归类 - A/B1 类 222 个重复文件删除(新结构已有内容副本) - 9 个旧独有空目录删除 - 270 处内部引用按 verified 映射改写 - 整改记录 #14 登记于 04-运维文档/部署运维 结果:docs 791 → 569 文件,顶层仅规范 8 类 + 治理文件,单树恢复。 残留:约 20 处指向从未存在文件的陈旧死链,归入独立文档卫生任务。 二、compose 双目录对齐(消除踩坑 A) - docker-compose.yml:nginx 前端挂载全部由根目录 frontend-*/dist 改为 src/frontend-*/dist(h5 / agent / admin / terminal) - docker-compose.dev.yml:dev 服务 build context 与卷同步改 src/ - 效果:本地 docker compose up 不再把根目录 stale dist 挂回, 与线上一致,分叉隐患消除(已 docker compose config 校验通过) 防复发铁律: - 重构须提交;仓库修复须 git stash -u 或先 commit - 新结构须 git add 并提交,避免再次 untracked 复活 - H5 改动只动 src/frontend-h5/,禁改根目录遗留 frontend-*/
46 lines
18 KiB
HTML
46 lines
18 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>分诊排查系统原型 v1.3 · 一体两面(Troubleshooting + Triage)</title>
|
||
<style>
|
||
:root{--bg:#f4f7f6;--panel:#fff;--line:#dce6e2;--text:#1f2937;--muted:#68776f;--green:#07c160;--green-soft:#e8f8ef;--blue:#2563eb;--amber:#d97706;--red:#dc2626;--nav:#16372d;--warning:#b45309;--shadow:0 10px 28px rgba(25,55,45,.08)}
|
||
*{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--text);font-family:"Microsoft YaHei","PingFang SC",sans-serif;font-size:14px}.app{display:grid;grid-template-columns:236px 1fr;min-height:100vh}.sidebar{background:var(--nav);color:#d9e9e3;padding:26px 18px}.brand{font-size:18px;font-weight:700;color:#fff;margin-bottom:34px}.brand small{display:block;font-size:11px;font-weight:400;color:#9ec3b5;margin-top:4px}.nav-title{font-size:11px;letter-spacing:.14em;color:#81a99a;margin:22px 10px 8px}.nav-item{padding:11px 12px;border-radius:6px;margin:4px 0;cursor:pointer}.nav-item.active,.nav-item:hover{background:#245343;color:#fff}.main{padding:28px 34px 46px}.topbar{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:22px}.title h1{margin:0 0 6px;font-size:24px}.title p{margin:0;color:var(--muted)}.badge{display:inline-flex;align-items:center;padding:4px 8px;border:1px solid #b7dec8;color:#167746;background:#effaf4;border-radius:4px;font-size:12px}.tabs{display:flex;border-bottom:1px solid var(--line);margin-bottom:22px;gap:28px}.tab{padding:11px 2px 12px;color:var(--muted);cursor:pointer;border-bottom:3px solid transparent}.tab.active{color:#146b43;border-color:var(--green);font-weight:700}.screen{display:none}.screen.active{display:block}.toolbar{display:flex;gap:10px;align-items:center;margin-bottom:16px}.input,.select{height:36px;border:1px solid var(--line);border-radius:5px;background:#fff;padding:0 11px;color:var(--text)}.input{width:260px}.select{width:140px}.spacer{flex:1}.btn{height:36px;padding:0 14px;border-radius:5px;border:1px solid #cbd8d3;background:#fff;color:#31443d;cursor:pointer;font-weight:600}.btn.primary{background:var(--green);border-color:var(--green);color:#fff}.btn.danger{color:var(--red)}.panel{background:var(--panel);border:1px solid var(--line);box-shadow:var(--shadow)}table{width:100%;border-collapse:collapse}th,td{text-align:left;padding:14px 16px;border-bottom:1px solid #edf2f0}th{font-size:12px;color:var(--muted);background:#f8faf9;font-weight:600}tr:last-child td{border-bottom:0}.name{font-weight:700}.desc{font-size:12px;color:var(--muted);margin-top:4px}.tag{display:inline-block;padding:3px 7px;border-radius:3px;background:#eef3f1;color:#486258;font-size:12px}.status{font-size:12px;font-weight:700}.published{color:#147746}.draft{color:var(--amber)}.off{color:#8a9490}.link{border:0;background:none;color:#176f4a;cursor:pointer;padding:0 6px}.editor{display:grid;grid-template-columns:310px 1fr;gap:16px}.form-panel,.canvas{background:#fff;border:1px solid var(--line);padding:18px}.section-title{font-size:15px;font-weight:700;margin:0 0 14px}.field{margin-bottom:14px}.field label{display:block;font-size:12px;color:var(--muted);margin-bottom:6px}.field input,.field textarea,.field select{width:100%;border:1px solid var(--line);border-radius:4px;padding:9px;background:#fff}.field textarea{min-height:78px;resize:vertical}.mode-switch{display:flex;gap:6px;margin-bottom:16px}.mode-switch button{flex:1;padding:8px;border:1px solid var(--line);background:#fff}.mode-switch button.active{background:var(--green-soft);color:#126c41;border-color:#99d6b4}.flow{display:flex;flex-direction:column;align-items:center;padding:8px 12px}.node{width:min(560px,90%);background:#fff;border:1px solid #cad9d3;padding:12px 14px;position:relative}.node strong{display:block}.node small{color:var(--muted)}.node.current{border-left:4px solid var(--green)}.node.decision{border-left:4px solid #e59b2f;background:#fffbf3}.connector{height:26px;width:1px;background:#a8bcb4}.branches{display:grid;grid-template-columns:1fr 1fr;gap:18px;width:92%;position:relative}.branch-label{text-align:center;color:var(--muted);font-size:12px;margin:5px}.validation{margin-top:18px;background:#f7faf8;border:1px solid var(--line);padding:12px}.ok{color:#147746}.warn{color:var(--amber)}.workspace{display:grid;grid-template-columns:1fr 290px;gap:16px}.chat{background:#fff;border:1px solid var(--line);min-height:520px;display:flex;flex-direction:column}.chat-head{padding:15px 17px;border-bottom:1px solid var(--line);font-weight:700}.messages{padding:18px;flex:1}.bubble{max-width:68%;padding:10px 12px;border-radius:8px;margin-bottom:10px;background:#eef3f1}.bubble.user{margin-left:auto;background:#dff5e8}.troublebar{border-top:1px solid var(--line);padding:14px;background:#fbfdfc}.steps{display:flex;gap:8px;overflow:auto;margin-top:10px}.step{min-width:115px;padding:9px;border:1px solid var(--line);background:#fff;font-size:12px}.step.done{background:var(--green-soft);color:#176b43}.step.current{border-color:var(--blue);box-shadow:inset 0 0 0 1px var(--blue)}.sidecard{background:#fff;border:1px solid var(--line);padding:16px}.progress{height:7px;background:#edf2f0;margin:12px 0}.progress span{display:block;width:42%;height:100%;background:var(--green)}.mobile-wrap{display:grid;grid-template-columns:330px 1fr;gap:28px;align-items:start}.phone{width:330px;min-height:620px;background:#fff;border:7px solid #24332d;border-radius:28px;overflow:hidden}.phone-head{padding:18px 18px 12px;background:#f7faf8;font-weight:700}.phone-body{padding:18px}.question{font-size:18px;line-height:1.5;margin:22px 0}.choice{width:100%;padding:13px;margin:8px 0;border:1px solid var(--line);background:#fff;text-align:left}.choice.primary{border-color:var(--green);background:var(--green-soft)}.summary{background:#fff;border:1px solid var(--line);padding:22px}.purpose-tabs{display:flex;gap:10px;margin-bottom:14px}.purpose-tab{padding:9px 14px;border:1px solid var(--line);background:#fff;border-radius:5px;cursor:pointer;font-size:13px;color:var(--muted)}.purpose-tab.active{background:var(--green-soft);color:#126c41;border-color:#99d6b4;font-weight:700}.callout{border-left:4px solid var(--green);background:var(--green-soft);padding:13px;margin:14px 0}.footer-note{margin-top:22px;color:var(--muted);font-size:12px}@media(max-width:980px){.app{grid-template-columns:1fr}.sidebar{display:none}.main{padding:20px}.editor,.workspace,.mobile-wrap{grid-template-columns:1fr}.phone{width:100%}}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="app">
|
||
<aside class="sidebar"><div class="brand">IT 智能服务台<small>分诊排查系统原型 v1.3 · REQ-坐席-007</small></div><div class="nav-title">运营配置</div><div class="nav-item active">分诊排查管理</div><div class="nav-item">快速回复规则</div><div class="nav-item">知识库配置</div><div class="nav-title">质量与分析</div><div class="nav-item">模板使用分析</div><div class="nav-item">操作审计</div></aside>
|
||
<main class="main">
|
||
<div class="topbar"><div class="title"><h1>分诊排查系统 · 一体两面</h1><p>统一编制、发布和执行高频故障的标准排查路径。一体两面:排查流程与问诊对话共用同一份后端真相,仅通过 purpose 字段区分。</p></div><span class="badge">原型 v1.3 · 待评审</span></div>
|
||
<div class="tabs"><div class="tab active" data-target="list">管理列表</div><div class="tab" data-target="edit">模板编辑</div><div class="tab" data-target="agent">坐席执行</div><div class="tab" data-target="h5">员工自助</div><div class="tab" data-target="triage">问诊流程</div></div>
|
||
<section id="list" class="screen active">
|
||
<div class="toolbar"><input class="input" placeholder="搜索名称或标签"><select class="select"><option>全部分类</option><option>VPN</option><option>账号</option><option>网络</option></select><select class="select"><option>全部状态</option><option>已发布</option><option>草稿</option><option>已停用</option></select><div class="spacer"></div><button class="btn">导入 JSON</button><button class="btn">导出全部</button><button class="btn primary" data-jump="edit">新建模板</button></div>
|
||
<div class="purpose-tabs"><div class="purpose-tab active">排查 Troubleshooting</div><div class="purpose-tab">问诊模板 Triage</div></div>
|
||
<div class="panel"><table><thead><tr><th>模板</th><th>分类</th><th>当前版本</th><th>状态</th><th>节点</th><th>预估时间</th><th>负责人/更新</th><th>操作</th></tr></thead><tbody>
|
||
<tr><td><div class="name">VPN 远程办公连接失败</div><div class="desc">检查客户端、网络、认证和策略状态</div></td><td><span class="tag">VPN</span></td><td>v1.3</td><td><span class="status published">已发布</span></td><td>12</td><td>8 分钟</td><td>宋献<br><span class="desc">07-28 10:32</span></td><td><button class="link" data-jump="edit">编辑</button><button class="link">版本</button><button class="link">停用</button></td></tr>
|
||
<tr><td><div class="name">企业微信无法登录</div><div class="desc">账号状态、设备时间和客户端修复</div></td><td><span class="tag">企业微信</span></td><td>v1.1</td><td><span class="status published">已发布</span></td><td>9</td><td>6 分钟</td><td>李明<br><span class="desc">07-26 16:18</span></td><td><button class="link">预览</button><button class="link">版本</button><button class="link">停用</button></td></tr>
|
||
<tr><td><div class="name">打印机无法打印</div><div class="desc">队列、连接、驱动和权限检查</div></td><td><span class="tag">外设</span></td><td>草稿</td><td><span class="status draft">待发布</span></td><td>7</td><td>5 分钟</td><td>王洁<br><span class="desc">07-28 09:04</span></td><td><button class="link" data-jump="edit">继续编辑</button><button class="link danger">归档</button></td></tr>
|
||
</tbody></table></div>
|
||
<div class="footer-note">说明:已发布版本不可直接覆盖;编辑会创建或更新草稿,发布后生成不可变版本快照。当前 Tab 仅展示 purpose=troubleshooting,问诊模板见上方 Triage Tab。</div>
|
||
</section>
|
||
<section id="edit" class="screen">
|
||
<div class="toolbar"><button class="btn">返回列表</button><div class="spacer"></div><button class="btn">双端预览</button><button class="btn">保存草稿</button><button class="btn primary" id="publishBtn">校验并发布</button></div>
|
||
<div class="editor"><div class="form-panel"><h3 class="section-title">模板基本信息</h3><div class="field"><label>模板用途 (purpose)</label><select disabled><option selected>排查 Troubleshooting</option></select><div class="desc" style="margin-top:4px;color:var(--warning)">模板创建后 purpose 不可修改;如需另一种用途,请基于此模板复制为新模板。</div></div><div class="field"><label>模板名称</label><input value="VPN 远程办公连接失败"></div><div class="field"><label>分类</label><select><option>VPN</option></select></div><div class="field"><label>员工可见范围</label><select><option>全体员工</option><option>指定部门</option><option>仅坐席</option></select></div><div class="field"><label>预估时间</label><input value="8 分钟"></div><div class="field"><label>版本说明</label><textarea>补充认证失败与终端策略异常分支。</textarea></div><h3 class="section-title">节点工具</h3><div class="mode-switch"><button class="active">结构化编辑</button><button>JSON 高级模式</button></div><button class="btn" style="width:100%;margin-bottom:8px">+ 步骤节点</button><button class="btn" style="width:100%;margin-bottom:8px">+ 判断节点</button><button class="btn" style="width:100%">+ 结束节点</button></div>
|
||
<div class="canvas"><h3 class="section-title">流程结构 · 12 节点</h3><div class="flow"><div class="node"><strong>开始:确认故障现象</strong><small>让员工描述报错、发生时间和网络环境</small></div><div class="connector"></div><div class="node decision"><strong>是否能打开其他互联网网站?</strong><small>判断基础网络是否可用</small></div><div class="branches"><div><div class="branch-label">是</div><div class="node current"><strong>检查 VPN 客户端版本</strong><small>低于 7.6.3 时引导升级</small></div></div><div><div class="branch-label">否</div><div class="node"><strong>进入网络连接模板</strong><small>关联:网络无法访问 v1.2</small></div></div></div></div><div class="validation"><strong class="ok">结构校验通过</strong><div class="desc">purpose=troubleshooting · 根节点 1 · 判断节点 3 · 结束节点 4 · 不可达节点 0 · 循环 0</div></div></div></div>
|
||
</section>
|
||
<section id="agent" class="screen"><div class="workspace"><div class="chat"><div class="chat-head">员工:张三 · VPN 连接失败</div><div class="messages"><div class="bubble user">今天在家连接 VPN 一直提示认证失败。</div><div class="bubble">我带你按标准流程检查。先确认其他网站是否可以正常打开?</div></div><div class="troublebar"><div style="display:flex;justify-content:space-between"><strong>排查步骤 · VPN 远程办公连接失败 v1.3</strong><button class="link">展开完整流程</button></div><div class="steps"><div class="step done">1. 确认网络<br>已完成</div><div class="step current">2. 检查版本<br>当前步骤</div><div class="step">3. 清除缓存<br>待处理</div><div class="step">4. 检查认证<br>待处理</div></div></div></div><aside class="sidecard"><h3 class="section-title">执行实例</h3><div class="desc">实例 TS-20260728-0318 · source=ai_recommend</div><div class="progress"><span></span></div><div>进度:5 / 12 节点</div><hr style="border:0;border-top:1px solid var(--line);margin:16px 0"><strong>当前操作</strong><p>请员工查看 VPN 客户端“关于”页面中的版本号。</p><button class="btn primary" style="width:100%">完成并进入下一步</button><button class="btn" style="width:100%;margin-top:8px">换其他模板(需确认)</button><button class="btn" style="width:100%;margin-top:8px">暂停排查</button><button class="btn danger" style="width:100%;margin-top:8px">结束:未解决</button><div class="callout" style="margin-top:14px"><strong>问诊中标识</strong><br>当 source=triage_fallback 时,排查栏顶部显示 “问诊中” 标识,问诊结束自动回到路由 + 手动双轨。</div></aside></div></section>
|
||
<section id="h5" class="screen"><div class="mobile-wrap"><div class="phone"><div class="phone-head">自助排查 · VPN 连接失败</div><div class="phone-body"><span class="tag">步骤 2 / 6 · purpose=troubleshooting</span><div class="question">你的电脑现在能正常打开其他互联网网站吗?</div><button class="choice primary">可以正常打开</button><button class="choice">无法打开或很慢</button><div class="desc" style="margin-top:18px">选择后系统将只展示与你情况相关的后续步骤。</div><div class="progress" style="margin-top:28px"><span style="width:33%"></span></div><button class="btn" style="width:100%;margin-top:18px">需要人工帮助</button></div></div><div class="summary"><h2 style="margin-top:0">员工端模板入口</h2><p>员工登录 H5 看到的模板分两类:</p><div class="callout"><strong>问诊模板(purpose=triage)</strong><br>始终置顶、始终可见,不受部门/角色过滤;作为路由无匹配时的兜底入口。</div><div class="callout"><strong>排查(purpose=troubleshooting)</strong><br>按可见范围(部门/角色)过滤后展示;员工可手动选择或接受 AI 推荐。</div><h3>转人工时自动携带上下文</h3><p>员工无需重新描述已经完成的操作,坐席收到以下摘要:</p><div class="callout"><strong>VPN 远程办公连接失败 v1.3</strong><br>已完成:确认网络环境、打开互联网网站<br>当前分支:互联网正常 → 检查 VPN 客户端<br>员工备注:提示认证失败,发生于 09:20</div><h3>员工端信息披露原则</h3><ul><li>只显示员工可理解、可安全执行的步骤。</li><li>终端策略、管理员命令和内部系统地址不向员工展示。</li><li>涉及设备检测、日志采集或修改配置时先说明用途。</li></ul></div></div></section>
|
||
<section id="triage" class="screen"><div class="purpose-tabs"><div class="purpose-tab">排查 Troubleshooting</div><div class="purpose-tab active">问诊模板 Triage</div></div><div class="panel" style="margin-top:16px"><table><thead><tr><th>模板</th><th>状态</th><th>节点</th><th>负责人/更新</th><th>操作</th></tr></thead><tbody>
|
||
<tr><td><div class="name">问诊对话(triage_intake)</div><div class="desc">路由无匹配时的兜底模板,通过短问题收敛故障方向</div></td><td><span class="status published">已发布</span></td><td>7</td><td>宋献<br><span class="desc">07-28 13:50</span></td><td><button class="link" data-jump="edit">编辑</button><button class="link">版本</button></td></tr>
|
||
</tbody></table></div><div class="callout" style="margin-top:18px"><strong>校验规则(purpose=triage)</strong><br>节点数 ≤ 10,深度 ≤ 4,必须含结束节点且 result=redirect;标签必须包含 triage 或 intake。</div>
|
||
<div class="footer-note">说明:问诊模板与排查共用同一份后端表、Schema、版本、审计、执行 API;不允许新增独立页面或独立表。</div>
|
||
</section>
|
||
</main></div>
|
||
<script>
|
||
const tabs=[...document.querySelectorAll('.tab')];const screens=[...document.querySelectorAll('.screen')];function openScreen(id){tabs.forEach(t=>t.classList.toggle('active',t.dataset.target===id));screens.forEach(s=>s.classList.toggle('active',s.id===id));window.scrollTo({top:0,behavior:'smooth'})}tabs.forEach(t=>t.addEventListener('click',()=>openScreen(t.dataset.target)));document.querySelectorAll('[data-jump]').forEach(b=>b.addEventListener('click',()=>openScreen(b.dataset.jump)));document.getElementById('publishBtn').addEventListener('click',()=>alert('校验通过:将发布为 v1.4。\n发布后历史版本保持不变,执行中的会话继续使用原版本。purpose 字段不可修改。'));document.querySelectorAll('.purpose-tab').forEach(t=>t.addEventListener('click',()=>{document.querySelectorAll('.purpose-tab').forEach(x=>x.classList.toggle('active',x===t));}));
|
||
</script>
|
||
</body>
|
||
</html>
|