365 lines
25 KiB
HTML
365 lines
25 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>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">编制:Duckula(AI) · 日期: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<日期>/</code>),禁用 <code>?v=</code> 查询参数打缓存。
|
||
</div>
|
||
</section>
|
||
|
||
<footer>
|
||
本架构图由《IT智能服务台-项目情况报告-2026-08-07》第二章「技术架构」派生可视化,可单独用于技术评审 / 入职培训 / 架构汇报。
|
||
关联源文档:项目状态看板 v1.9.1-FROZEN、IT服务台AI化战略路线图 v1.0。
|
||
</footer>
|
||
|
||
</div>
|
||
</body>
|
||
</html>
|