Files
wecom_it_smart_desk/IT智能服务台-技术架构图-2026-08-07.html
T

365 lines
25 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.0">
<title>IT 智能服务台 — 技术架构图</title>
<style>
:root{
--bg:#eceff3; --card:#ffffff; --ink:#0f172a; --muted:#475569;
--line:#cbd2da; --accent:#07C160; --accent-d:#047857;
--blue:#1769E0; --purple:#7c3aed; --orange:#b45309; --gray:#6b7280;
}
*{box-sizing:border-box;}
body{
margin:0; background:var(--bg); color:var(--ink);
font-family:"Microsoft YaHei","PingFang SC",system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial,sans-serif;
line-height:1.6;
}
.wrap{max-width:1240px; margin:0 auto; padding:32px 24px 64px;}
header.doc{
border-left:6px solid var(--accent); padding:8px 0 8px 18px; margin-bottom:28px;
}
header.doc h1{margin:0 0 6px; font-size:26px; letter-spacing:.5px;}
header.doc .sub{color:var(--muted); font-size:13px;}
header.doc .meta{color:var(--muted); font-size:12px; margin-top:8px;}
section{margin:40px 0;}
section h2{
font-size:19px; margin:0 0 16px; padding-bottom:8px;
border-bottom:2px solid var(--line); color:var(--ink);
}
section h2 .badge{
display:inline-block; background:var(--accent); color:#fff; font-size:12px;
border-radius:6px; padding:1px 9px; margin-right:10px; vertical-align:middle;
}
.diagram-card{
background:var(--card); border:1px solid var(--line); border-radius:14px;
padding:18px 18px 10px; box-shadow:0 1px 3px rgba(0,0,0,.04);
}
svg.arch{width:100%; height:auto; display:block;}
table.stk{width:100%; border-collapse:collapse; background:var(--card);
border:1px solid var(--line); border-radius:12px; overflow:hidden; font-size:14px;}
table.stk th,table.stk td{border-bottom:1px solid var(--line); padding:11px 14px; text-align:left; vertical-align:top;}
table.stk th{background:#f0fdf4; color:var(--accent-d); font-weight:600; width:160px;}
table.stk tr:last-child td{border-bottom:none;}
table.stk td code{background:#eef2f6; border-radius:4px; padding:1px 6px; font-size:12.5px; color:#0f766e;}
.flow-desc{font-size:13.5px; color:var(--muted); margin:10px 2px 0;}
.legend{display:flex; flex-wrap:wrap; gap:14px; margin:14px 2px 0; font-size:12.5px; color:var(--muted);}
.legend span{display:inline-flex; align-items:center; gap:6px;}
.legend i{width:14px; height:14px; border-radius:4px; display:inline-block; border:2px solid #fff; box-shadow:0 0 0 1px var(--line);}
.note{font-size:12.5px; color:var(--muted); margin-top:14px; padding:10px 14px; background:#fffbe6; border:1px solid #fde68a; border-radius:10px;}
footer{margin-top:48px; color:var(--muted); font-size:12px; border-top:1px solid var(--line); padding-top:16px;}
</style>
</head>
<body>
<div class="wrap">
<header class="doc">
<h1>IT 智能服务台 — 技术架构</h1>
<div class="sub">基于《IT智能服务台-项目情况报告-2026-08-07》第二章「技术架构」可视化</div>
<div class="meta">编制:DuckulaAI · 日期:2026-08-07 · 数据来源:项目记忆库 / 战略路线图 v1.0</div>
</header>
<!-- ============ 主架构图 ============ -->
<section>
<h2><span class="badge">图 1</span>总体技术架构(六层)</h2>
<div class="diagram-card">
<svg class="arch" viewBox="0 0 1240 940" xmlns="http://www.w3.org/2000/svg" font-family="Microsoft YaHei, sans-serif">
<defs>
<marker id="ar" markerWidth="11" markerHeight="11" refX="8.5" refY="3.2" orient="auto">
<path d="M0,0 L9,3.2 L0,6.4 Z" fill="#047857"/>
</marker>
<marker id="arg" markerWidth="11" markerHeight="11" refX="8.5" refY="3.2" orient="auto">
<path d="M0,0 L9,3.2 L0,6.4 Z" fill="#4b5563"/>
</marker>
</defs>
<!-- layer labels -->
<g font-size="14" font-weight="700" fill="#4b5563">
<text x="14" y="86">① 接入层</text>
<text x="14" y="226">② 通道层</text>
<text x="14" y="400">③ 后端层</text>
<text x="14" y="566">④ AI 中台</text>
<text x="14" y="706">⑤ 数据层</text>
<text x="14" y="846">⑥ 外部集成</text>
</g>
<!-- ===== Layer 1 ===== -->
<g>
<rect x="60" y="40" width="250" height="82" rx="10" fill="#eff6ff" stroke="#1d4ed8" stroke-width="2.5"/>
<text x="185" y="72" text-anchor="middle" font-size="15" font-weight="700" fill="#0f172a">员工端 H5</text>
<text x="185" y="94" text-anchor="middle" font-size="11.5" fill="#475569">Vue3 + Vant4 · 企微免登</text>
<rect x="495" y="40" width="250" height="82" rx="10" fill="#eff6ff" stroke="#1d4ed8" stroke-width="2.5"/>
<text x="620" y="72" text-anchor="middle" font-size="15" font-weight="700" fill="#0f172a">坐席端 Web</text>
<text x="620" y="94" text-anchor="middle" font-size="11.5" fill="#475569">Vue3 + Element Plus · 三栏</text>
<rect x="930" y="40" width="250" height="82" rx="10" fill="#eff6ff" stroke="#1d4ed8" stroke-width="2.5"/>
<text x="1055" y="72" text-anchor="middle" font-size="15" font-weight="700" fill="#0f172a">管理端 Web</text>
<text x="1055" y="94" text-anchor="middle" font-size="11.5" fill="#475569">Vue3 + Element + Tailwind</text>
</g>
<!-- ===== Layer 2 ===== -->
<g>
<rect x="60" y="180" width="560" height="82" rx="10" fill="#ecfdf5" stroke="#047857" stroke-width="2.5"/>
<text x="340" y="212" text-anchor="middle" font-size="15" font-weight="700" fill="#0f172a">WebSocket 双连接池</text>
<text x="340" y="234" text-anchor="middle" font-size="11.5" fill="#475569">employee_connections(H5) + active_connections(Agent)</text>
<rect x="650" y="180" width="530" height="82" rx="10" fill="#ecfdf5" stroke="#047857" stroke-width="2.5"/>
<text x="915" y="212" text-anchor="middle" font-size="15" font-weight="700" fill="#0f172a">企微 JS-SDK 双鉴权</text>
<text x="915" y="234" text-anchor="middle" font-size="11.5" fill="#475569">wx.config + wx.agentConfig(不可混用)</text>
</g>
<!-- ===== Layer 3 (container) ===== -->
<rect x="60" y="320" width="1120" height="158" rx="14" fill="#dcfce7" stroke="#047857" stroke-width="2.5"/>
<text x="80" y="348" font-size="14.5" font-weight="700" fill="#05914a">③ 后端服务层(FastAPI · SQLAlchemy · Redis 客户端)</text>
<g>
<!-- 6 inner boxes -->
<g>
<rect x="80" y="362" width="170" height="96" rx="9" fill="#ffffff" stroke="#047857" stroke-width="2"/>
<text x="165" y="392" text-anchor="middle" font-size="13.5" font-weight="700" fill="#0f172a">会话路由 D1</text>
<text x="165" y="414" text-anchor="middle" font-size="10.5" fill="#475569">意图/业务分类透传</text>
</g>
<g>
<rect x="258" y="362" width="170" height="96" rx="9" fill="#ffffff" stroke="#047857" stroke-width="2"/>
<text x="343" y="392" text-anchor="middle" font-size="13.5" font-weight="700" fill="#0f172a">消息处理管线</text>
<text x="343" y="414" text-anchor="middle" font-size="10.5" fill="#475569">process_h5_ai_reply</text>
</g>
<g>
<rect x="436" y="362" width="170" height="96" rx="9" fill="#ffffff" stroke="#047857" stroke-width="2"/>
<text x="521" y="392" text-anchor="middle" font-size="13.5" font-weight="700" fill="#0f172a">诊断→修复闭环</text>
<text x="521" y="414" text-anchor="middle" font-size="10.5" fill="#475569">queue/quiz/closing</text>
</g>
<g>
<rect x="614" y="362" width="170" height="96" rx="9" fill="#ffffff" stroke="#047857" stroke-width="2"/>
<text x="699" y="392" text-anchor="middle" font-size="13.5" font-weight="700" fill="#0f172a">审批待办桥接</text>
<text x="699" y="414" text-anchor="middle" font-size="10.5" fill="#475569">12 类 18 流程</text>
</g>
<g>
<rect x="792" y="362" width="170" height="96" rx="9" fill="#ffffff" stroke="#047857" stroke-width="2"/>
<text x="877" y="392" text-anchor="middle" font-size="13.5" font-weight="700" fill="#0f172a">内容审核</text>
<text x="877" y="414" text-anchor="middle" font-size="10.5" fill="#475569">content_moderation</text>
</g>
<g>
<rect x="970" y="362" width="170" height="96" rx="9" fill="#ffffff" stroke="#047857" stroke-width="2"/>
<text x="1055" y="392" text-anchor="middle" font-size="13.5" font-weight="700" fill="#0f172a">资产管理</text>
<text x="1055" y="414" text-anchor="middle" font-size="10.5" fill="#475569">IT 资产推送</text>
</g>
</g>
<!-- ===== Layer 4 ===== -->
<g>
<rect x="60" y="520" width="340" height="82" rx="10" fill="#f5f3ff" stroke="#6d28d9" stroke-width="2.5"/>
<text x="230" y="552" text-anchor="middle" font-size="15" font-weight="700" fill="#0f172a">Dify 工作流编排</text>
<text x="230" y="574" text-anchor="middle" font-size="11.5" fill="#475569">主对话 / 分诊 / 审批 / 知识</text>
<rect x="420" y="520" width="300" height="82" rx="10" fill="#f5f3ff" stroke="#6d28d9" stroke-width="2.5"/>
<text x="570" y="552" text-anchor="middle" font-size="15" font-weight="700" fill="#0f172a">RAGFlow 知识检索</text>
<text x="570" y="574" text-anchor="middle" font-size="11.5" fill="#475569">10.80.0.85:8080</text>
<rect x="730" y="520" width="240" height="82" rx="10" fill="#f5f3ff" stroke="#6d28d9" stroke-width="2.5"/>
<text x="850" y="552" text-anchor="middle" font-size="15" font-weight="700" fill="#0f172a">千问大模型</text>
<text x="850" y="574" text-anchor="middle" font-size="11.5" fill="#475569">LLM 推理</text>
<rect x="980" y="520" width="200" height="82" rx="10" fill="#ede9fe" stroke="#6d28d9" stroke-width="2.5"/>
<text x="1080" y="552" text-anchor="middle" font-size="15" font-weight="700" fill="#0f172a">单通道消息</text>
<text x="1080" y="574" text-anchor="middle" font-size="11.5" fill="#475569">{text,action,options}</text>
</g>
<!-- ===== Layer 5 ===== -->
<g>
<rect x="330" y="660" width="320" height="82" rx="10" fill="#fff7ed" stroke="#c2410c" stroke-width="2.5"/>
<text x="490" y="692" text-anchor="middle" font-size="15" font-weight="700" fill="#0f172a">PostgreSQL</text>
<text x="490" y="714" text-anchor="middle" font-size="11.5" fill="#475569">会话 / 工单 / 知识库 / 审批</text>
<rect x="670" y="660" width="320" height="82" rx="10" fill="#fff7ed" stroke="#c2410c" stroke-width="2.5"/>
<text x="830" y="692" text-anchor="middle" font-size="15" font-weight="700" fill="#0f172a">Redis</text>
<text x="830" y="714" text-anchor="middle" font-size="11.5" fill="#475569">会话状态 / 队列 / 缓存 / WS 池</text>
</g>
<!-- ===== Layer 6 ===== -->
<g>
<rect x="60" y="800" width="360" height="82" rx="10" fill="#f3f4f6" stroke="#374151" stroke-width="2.5"/>
<text x="240" y="832" text-anchor="middle" font-size="15" font-weight="700" fill="#0f172a">企微通讯录 API</text>
<text x="240" y="854" text-anchor="middle" font-size="11.5" fill="#475569">Secret 鉴权 · access_token</text>
<rect x="440" y="800" width="360" height="82" rx="10" fill="#f3f4f6" stroke="#374151" stroke-width="2.5"/>
<text x="620" y="832" text-anchor="middle" font-size="15" font-weight="700" fill="#0f172a">火绒、联软、aTrust</text>
<text x="620" y="854" text-anchor="middle" font-size="11.5" fill="#475569">终端安全 → 用户 映射</text>
<rect x="820" y="800" width="360" height="82" rx="10" fill="#f3f4f6" stroke="#374151" stroke-width="2.5"/>
<text x="1000" y="832" text-anchor="middle" font-size="15" font-weight="700" fill="#0f172a">ITSM 工单平台</text>
<text x="1000" y="854" text-anchor="middle" font-size="11.5" fill="#475569">待 API 授权(BLK-B</text>
</g>
<!-- ===== Arrows ===== -->
<!-- L1 -> L2 -->
<line x1="185" y1="122" x2="240" y2="178" stroke="#4b5563" stroke-width="2.5" marker-end="url(#arg)"/>
<line x1="620" y1="122" x2="380" y2="178" stroke="#4b5563" stroke-width="2.5" marker-end="url(#arg)"/>
<line x1="1055" y1="122" x2="860" y2="178" stroke="#4b5563" stroke-width="2.5" marker-end="url(#arg)"/>
<!-- L2 -> L3 -->
<line x1="320" y1="262" x2="340" y2="318" stroke="#047857" stroke-width="2.5" marker-end="url(#ar)"/>
<line x1="915" y1="262" x2="900" y2="318" stroke="#047857" stroke-width="2.5" marker-end="url(#ar)"/>
<!-- L3 -> L4 (AI calls) -->
<line x1="230" y1="478" x2="230" y2="518" stroke="#047857" stroke-width="2.5" marker-end="url(#ar)"/>
<line x1="570" y1="478" x2="570" y2="518" stroke="#047857" stroke-width="2.5" marker-end="url(#ar)"/>
<line x1="850" y1="478" x2="850" y2="518" stroke="#047857" stroke-width="2.5" marker-end="url(#ar)"/>
<line x1="1080" y1="478" x2="1080" y2="518" stroke="#047857" stroke-width="2.5" marker-end="url(#ar)"/>
<text x="1175" y="505" text-anchor="end" font-size="11" fill="#05914a">AI 推理调用</text>
<!-- L3 -> L5 (persistence) -->
<line x1="490" y1="478" x2="490" y2="658" stroke="#047857" stroke-width="2.5" marker-end="url(#ar)"/>
<line x1="830" y1="478" x2="830" y2="658" stroke="#047857" stroke-width="2.5" marker-end="url(#ar)"/>
<text x="640" y="575" text-anchor="middle" font-size="11" fill="#b45309">持久化读写</text>
<!-- L3 -> L6 (integration, dashed) -->
<path d="M240,478 C240,640 240,720 240,798" stroke="#4b5563" stroke-width="2.5" stroke-dasharray="6 5" fill="none" marker-end="url(#arg)"/>
<path d="M620,478 C620,660 620,740 620,798" stroke="#4b5563" stroke-width="2.5" stroke-dasharray="6 5" fill="none" marker-end="url(#arg)"/>
<path d="M699,478 C699,640 1000,720 1000,798" stroke="#4b5563" stroke-width="2.5" stroke-dasharray="6 5" fill="none" marker-end="url(#arg)"/>
<text x="900" y="640" text-anchor="middle" font-size="11" fill="#475569">外部系统集成</text>
</svg>
<div class="legend">
<span><i style="background:#1769E0"></i>用户接入(前端)</span>
<span><i style="background:#07C160"></i>实时通道 / 后端服务</span>
<span><i style="background:#7c3aed"></i>AI 中台</span>
<span><i style="background:#b45309"></i>数据层</span>
<span><i style="background:#6b7280"></i>外部系统集成</span>
<span><i style="background:#9ca3af"></i>虚线 = 集成/旁路调用</span>
</div>
</div>
</section>
<!-- ============ WebSocket 拓扑 ============ -->
<section>
<h2><span class="badge">图 2</span>WebSocket 双连接池与消息推送拓扑</h2>
<div class="diagram-card">
<svg class="arch" viewBox="0 0 1180 300" xmlns="http://www.w3.org/2000/svg" font-family="Microsoft YaHei, sans-serif">
<defs>
<marker id="ar2" markerWidth="11" markerHeight="11" refX="8.5" refY="3.2" orient="auto">
<path d="M0,0 L9,3.2 L0,6.4 Z" fill="#047857"/>
</marker>
</defs>
<!-- H5 -->
<rect x="40" y="40" width="220" height="80" rx="10" fill="#eff6ff" stroke="#1d4ed8" stroke-width="2.5"/>
<text x="150" y="72" text-anchor="middle" font-size="14" font-weight="700">员工端 H5</text>
<text x="150" y="94" text-anchor="middle" font-size="11" fill="#475569">employee_connections 池</text>
<!-- Agent -->
<rect x="40" y="180" width="220" height="80" rx="10" fill="#eff6ff" stroke="#1d4ed8" stroke-width="2.5"/>
<text x="150" y="212" text-anchor="middle" font-size="14" font-weight="700">坐席端 Web</text>
<text x="150" y="234" text-anchor="middle" font-size="11" fill="#475569">active_connections 池</text>
<!-- Backend hub -->
<rect x="470" y="110" width="240" height="80" rx="10" fill="#dcfce7" stroke="#047857" stroke-width="2.5"/>
<text x="590" y="142" text-anchor="middle" font-size="14" font-weight="700">后端 WS 网关</text>
<text x="590" y="164" text-anchor="middle" font-size="11" fill="#475569">双池管理 + 广播</text>
<!-- AI layer -->
<rect x="900" y="110" width="240" height="80" rx="10" fill="#ede9fe" stroke="#6d28d9" stroke-width="2.5"/>
<text x="1020" y="142" text-anchor="middle" font-size="14" font-weight="700">AI 推理 / 诊断</text>
<text x="1020" y="164" text-anchor="middle" font-size="11" fill="#475569">Dify + RAGFlow + 千问</text>
<!-- arrows -->
<line x1="260" y1="80" x2="468" y2="128" stroke="#047857" stroke-width="2.5" marker-end="url(#ar2)"/>
<line x1="260" y1="220" x2="468" y2="172" stroke="#047857" stroke-width="2.5" marker-end="url(#ar2)"/>
<line x1="710" y1="150" x2="898" y2="150" stroke="#7c3aed" stroke-width="2.5" marker-end="url(#ar2)"/>
<line x1="900" y1="150" x2="712" y2="150" stroke="#4b5563" stroke-width="2.5" marker-end="url(#arg)"/>
<!-- push labels -->
<text x="360" y="100" text-anchor="middle" font-size="11" fill="#05914a">ai_reply / ai_thinking</text>
<text x="360" y="205" text-anchor="middle" font-size="11" fill="#05914a">agent 操作 / 接管</text>
<text x="805" y="138" text-anchor="middle" font-size="11" fill="#7c3aed">推理请求</text>
<text x="805" y="170" text-anchor="middle" font-size="10.5" fill="#4b5563">统一消息回传</text>
</svg>
<p class="flow-desc">
后端维护两套独立连接池:<b>employee_connections</b>(员工 H5)与 <b>active_connections</b>(坐席 Web)。
一次 AI 推理产出的统一消息 <code>{text,action,options}</code> 经后端解析后,拆分为
<b>ai_reply</b>(聊天气泡)与 <b>dynamic_recommend</b>(侧边栏卡片),并通过 <b>ai_thinking</b> 事件同时推送两端,实现"员工看到思考过程、坐席同步可见"的协同体验。
</p>
</div>
</section>
<!-- ============ AI 单通道消息流 ============ -->
<section>
<h2><span class="badge">图 3</span>AI 单通道统一消息流(Dify → 后端 → 双端)</h2>
<div class="diagram-card">
<svg class="arch" viewBox="0 0 1180 220" xmlns="http://www.w3.org/2000/svg" font-family="Microsoft YaHei, sans-serif">
<defs>
<marker id="ar3" markerWidth="11" markerHeight="11" refX="8.5" refY="3.2" orient="auto">
<path d="M0,0 L9,3.2 L0,6.4 Z" fill="#047857"/>
</marker>
</defs>
<!-- node 1 -->
<rect x="30" y="70" width="200" height="80" rx="10" fill="#ede9fe" stroke="#6d28d9" stroke-width="2.5"/>
<text x="130" y="102" text-anchor="middle" font-size="13.5" font-weight="700">Dify 输出</text>
<text x="130" y="124" text-anchor="middle" font-size="11" fill="#475569">{text, action, options}</text>
<!-- node 2 -->
<rect x="340" y="70" width="240" height="80" rx="10" fill="#dcfce7" stroke="#047857" stroke-width="2.5"/>
<text x="460" y="102" text-anchor="middle" font-size="13.5" font-weight="700">后端解析 & 分发</text>
<text x="460" y="124" text-anchor="middle" font-size="11" fill="#475569">JSON 解析 + 双 WS 推送</text>
<!-- node 3 H5 -->
<rect x="720" y="20" width="240" height="70" rx="10" fill="#eff6ff" stroke="#1d4ed8" stroke-width="2.5"/>
<text x="840" y="50" text-anchor="middle" font-size="13" font-weight="700">员工 H5</text>
<text x="840" y="72" text-anchor="middle" font-size="10.5" fill="#475569">气泡文字 + 侧栏推荐卡片</text>
<!-- node 4 Agent -->
<rect x="720" y="130" width="240" height="70" rx="10" fill="#eff6ff" stroke="#1d4ed8" stroke-width="2.5"/>
<text x="840" y="160" text-anchor="middle" font-size="13" font-weight="700">坐席 Web</text>
<text x="840" y="182" text-anchor="middle" font-size="10.5" fill="#475569">AI 思考指示器 + 草稿</text>
<!-- arrows -->
<line x1="230" y1="110" x2="338" y2="110" stroke="#047857" stroke-width="2.5" marker-end="url(#ar3)"/>
<line x1="580" y1="95" x2="718" y2="55" stroke="#047857" stroke-width="2.5" marker-end="url(#ar3)"/>
<line x1="580" y1="125" x2="718" y2="160" stroke="#047857" stroke-width="2.5" marker-end="url(#ar3)"/>
<text x="650" y="80" text-anchor="middle" font-size="10.5" fill="#05914a">ai_reply</text>
<text x="650" y="155" text-anchor="middle" font-size="10.5" fill="#05914a">ai_thinking</text>
</svg>
<p class="flow-desc">
早期各场景各自调用 AI、消息格式不统一。重构后统一为 <b>单通道</b>Dify 仅输出结构化 JSON <code>{text, action, options}</code>
后端做阻塞式解析与降级(30s 超时 / 15s still_thinking),再向双端推送——
文字进聊天气泡、选项卡片进侧边栏、思考状态两端同步,彻底消除"员工与坐席看到不同 AI 状态"的断层。
</p>
</div>
</section>
<!-- ============ 技术栈明细 ============ -->
<section>
<h2><span class="badge">表 1</span>技术栈明细</h2>
<table class="stk">
<tr><th>分层</th><td>技术选型与说明</td></tr>
<tr><th>员工前端</th><td><code>Vue3</code> + <code>Vant4</code>,运行于企微 H5 环境,集成企微 JS-SDK(OAuth2 免登、语音转文字、原生审批表单)</td></tr>
<tr><th>坐席 / 管理前端</th><td><code>Vue3</code> + <code>Element Plus</code>(坐席三栏工作台)/ <code>Tailwind</code>(管理后台);键盘快捷键 v2.3 中央管理器</td></tr>
<tr><th>后端</th><td><code>FastAPI</code> + <code>SQLAlchemy</code> + <code>PostgreSQL</code> + <code>Redis</code>;消息管线 <code>process_h5_ai_reply</code>、诊断闭环(queue/quiz/closing)、内容审核</td></tr>
<tr><th>AI 中台</th><td><code>Dify</code>(工作流编排:主对话/分诊/审批意图/知识)+ <code>RAGFlow</code>(知识检索,10.80.0.85:8080+ <code>千问大模型</code>LLM 推理)</td></tr>
<tr><th>实时通道</th><td><code>WebSocket</code> 双连接池(employee_connections / active_connections),推送 ai_reply / dynamic_recommend / ai_thinking</td></tr>
<tr><th>外部集成</th><td>企微通讯录(Secret 鉴权、access_token 缓存)+ JS-SDK 双鉴权;联软(主)/aTrust( VPN )/eHR(静态) 终端→用户映射</td></tr>
<tr><th>部署</th><td><code>Docker Compose</code>:后端 + nginx + 多前端 <code>ro bind mount</code>;WAF 前置按 path 缓存,版本化 PATH + 302 跳板破除缓存</td></tr>
</table>
</section>
<!-- ============ 外部依赖 ============ -->
<section>
<h2><span class="badge">表 2</span>外部依赖与对接状态</h2>
<table class="stk">
<tr><th>系统</th><td>用途 / 接入点</td><td>状态</td></tr>
<tr><th>Dify</th><td>主对话 <code>app-8f0f3d62…</code>、分诊 <code>app-z3S9…</code>、审批 <code>app-7jkRk…</code>(老应用 <code>app-UaTWY…</code> 已禁用)</td><td>✅ 已上线</td></tr>
<tr><th>RAGFlow</th><td>知识检索服务 <code>http://10.80.0.85:8080/</code>API :9380</td><td>✅ 已上线</td></tr>
<tr><th>企微通讯录</th><td>通讯录 Secret 鉴权、<code>access_token</code> 缓存(Redis key <code>wecom:contact_access_token</code>);JS-SDK <code>wx.config</code> + <code>wx.agentConfig</code> 双鉴权</td><td>✅ 已上线</td></tr>
<tr><th>联软 / aTrust / eHR</th><td>终端 IP / 主机名 → 用户身份映射(联软为主,aTrust 备选,eHR 静态兜底)</td><td>✅ 已接入</td></tr>
<tr><th>ITSM 工单平台</th><td>工单卡片跳转与目标系统打通(需 app_id/app_secret 授权)</td><td>⏸️ 待授权(BLK-B,阻塞 26 天)</td></tr>
<tr><th>企微会议室</th><td>会议室预定功能所需 Secret(影响 /itterminal/</td><td>⏸️ 待申请(BLK-A,阻塞 26 天)</td></tr>
</table>
<div class="note">
⚠️ <b>部署铁律提示</b>:所有前端 <code>dist</code> 均为只读 bind mount,仅能在宿主机源路径(含 <code>/src/</code>,如 <code>/opt/wecom-it-desk/src/frontend-h5/dist</code>)操作;
域名前置 WAF 按 path 缓存、忽略 query,故发版须用<b>版本化 PATH + 302 跳板</b>(如 <code>/h5/go → /h5/v&lt;日期&gt;/</code>),禁用 <code>?v=</code> 查询参数打缓存。
</div>
</section>
<footer>
本架构图由《IT智能服务台-项目情况报告-2026-08-07》第二章「技术架构」派生可视化,可单独用于技术评审 / 入职培训 / 架构汇报。
关联源文档:项目状态看板 v1.9.1-FROZEN、IT服务台AI化战略路线图 v1.0。
</footer>
</div>
</body>
</html>