| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 |
- <svg xmlns="http://www.w3.org/2000/svg" width="2800" height="1760" viewBox="0 0 2800 1760">
- <defs>
- <linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
- <stop offset="0%" stop-color="#f8fbff"/>
- <stop offset="52%" stop-color="#eef6ff"/>
- <stop offset="100%" stop-color="#f7fbff"/>
- </linearGradient>
- <filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
- <feDropShadow dx="0" dy="8" stdDeviation="8" flood-color="#0f172a" flood-opacity="0.13"/>
- </filter>
- <marker id="arrowBlue" markerWidth="13" markerHeight="13" refX="11" refY="6.5" orient="auto">
- <path d="M0,0 L13,6.5 L0,13 Z" fill="#2563eb"/>
- </marker>
- <marker id="arrowGreen" markerWidth="13" markerHeight="13" refX="11" refY="6.5" orient="auto">
- <path d="M0,0 L13,6.5 L0,13 Z" fill="#16a34a"/>
- </marker>
- <marker id="arrowOrange" markerWidth="13" markerHeight="13" refX="11" refY="6.5" orient="auto">
- <path d="M0,0 L13,6.5 L0,13 Z" fill="#f97316"/>
- </marker>
- <style>
- .title { font: 800 48px "PingFang SC","Microsoft YaHei",Arial; fill:#07143f; letter-spacing: 1px; }
- .subtitle { font: 500 23px "PingFang SC","Microsoft YaHei",Arial; fill:#38527a; }
- .layer-title { font: 800 25px "PingFang SC","Microsoft YaHei",Arial; fill:#0f172a; }
- .layer-note { font: 500 16px "PingFang SC","Microsoft YaHei",Arial; fill:#64748b; }
- .box-title { font: 800 21px "PingFang SC","Microsoft YaHei",Arial; fill:#0f172a; }
- .box-sub { font: 500 15px "PingFang SC","Microsoft YaHei",Arial; fill:#334155; }
- .mini { font: 500 13px "PingFang SC","Microsoft YaHei",Arial; fill:#475569; }
- .tag { font: 800 14px "PingFang SC","Microsoft YaHei",Arial; fill:white; }
- .legend { font: 700 16px "PingFang SC","Microsoft YaHei",Arial; fill:#1e293b; }
- .lane { fill:white; stroke:#cbd5e1; stroke-width:1.5; rx:22; filter:url(#shadow); }
- .entry { fill:#dbeafe; stroke:#2563eb; stroke-width:2; rx:16; }
- .current { fill:#eff6ff; stroke:#60a5fa; stroke-width:2; rx:14; }
- .legacy { fill:#fff7ed; stroke:#fb923c; stroke-width:2.5; rx:14; }
- .planned { fill:#ecfdf5; stroke:#22c55e; stroke-width:2.2; rx:14; }
- .impl { fill:#f0fdf4; stroke:#16a34a; stroke-width:2; rx:14; }
- .future { fill:#ecfeff; stroke:#06b6d4; stroke-width:2; stroke-dasharray:8 7; rx:14; }
- .external { fill:#faf5ff; stroke:#a855f7; stroke-width:2; rx:14; }
- .data { fill:#fff1f2; stroke:#fb7185; stroke-width:2; rx:14; }
- .common { fill:#f8fafc; stroke:#94a3b8; stroke-width:2; rx:14; }
- .call { stroke:#2563eb; stroke-width:4; fill:none; marker-end:url(#arrowBlue); }
- .event { stroke:#16a34a; stroke-width:4; fill:none; marker-end:url(#arrowGreen); stroke-dasharray:10 8; }
- .split { stroke:#f97316; stroke-width:4; fill:none; marker-end:url(#arrowOrange); stroke-dasharray:7 6; }
- .thin { stroke-width:2.5; }
- </style>
- </defs>
- <rect width="2800" height="1760" fill="url(#bg)"/>
- <text x="80" y="72" class="title">医梦 AI 中台工程模块架构图|现状 → 目标模块化 → 未来可拆服务</text>
- <text x="82" y="112" class="subtitle">原则:3 人团队先做模块化单体;不做过早微服务;把 emoon-mcp-api 拆成 emoon-ai-agent-api / emoon-ai-card-api / emoon-ai-mcp-api;MCP / Audio / IoMT / Followup 保留服务化边界。</text>
- <!-- legend -->
- <rect x="2150" y="42" width="570" height="92" rx="18" fill="white" stroke="#cbd5e1" filter="url(#shadow)"/>
- <rect x="2180" y="66" width="24" height="18" class="current"/><text x="2214" y="82" class="legend">现有模块</text>
- <rect x="2330" y="66" width="24" height="18" class="planned"/><text x="2364" y="82" class="legend">规划 API</text>
- <rect x="2480" y="66" width="24" height="18" class="impl"/><text x="2514" y="82" class="legend">领域实现</text>
- <rect x="2180" y="101" width="24" height="18" class="future"/><text x="2214" y="117" class="legend">未来可拆</text>
- <rect x="2330" y="101" width="24" height="18" class="data"/><text x="2364" y="117" class="legend">数据事实</text>
- <rect x="2480" y="101" width="24" height="18" class="legacy"/><text x="2514" y="117" class="legend">待拆旧模块</text>
- <!-- lanes -->
- <rect x="60" y="160" width="2680" height="145" class="lane"/>
- <text x="86" y="198" class="layer-title">L0|外部触点</text>
- <text x="86" y="224" class="layer-note">患者、医护、运营、设备与语音网关只认平台入口,不直接碰账本和 HIS</text>
- <rect x="60" y="330" width="2680" height="160" class="lane"/>
- <text x="86" y="368" class="layer-title">L1|启动应用层(现有)</text>
- <text x="86" y="394" class="layer-note">少量 Spring Boot 启动应用:管理后台 + 开放平台 + 调度/监控</text>
- <rect x="60" y="520" width="2680" height="245" class="lane"/>
- <text x="86" y="558" class="layer-title">L2|当前 Maven 基座(现状)</text>
- <text x="86" y="584" class="layer-note">RuoYi-Vue-Plus 风格聚合工程,已有 common / modules-api / modules / extend 分层</text>
- <rect x="60" y="790" width="2680" height="360" class="lane"/>
- <text x="86" y="828" class="layer-title">L3|目标领域模块(先模块化单体,不做全量微服务)</text>
- <text x="86" y="854" class="layer-note">模块按业务边界拆,API 与实现分离;emoon-mcp-api 的混合职责拆成三个 API 模块</text>
- <rect x="60" y="1180" width="2680" height="205" class="lane"/>
- <text x="86" y="1218" class="layer-title">L4|未来可独立部署边界</text>
- <text x="86" y="1244" class="layer-note">只有出现院内网络隔离、长连接、设备接入、外呼网关、高耗时任务时才拆</text>
- <rect x="60" y="1415" width="2680" height="160" class="lane"/>
- <text x="86" y="1453" class="layer-title">L5|外部系统与 AI 能力</text>
- <text x="86" y="1479" class="layer-note">Dify 负责复杂流程,DirectLLM 可作为 L1 主引擎;HIS 系统只通过 MCP 工具访问</text>
- <rect x="60" y="1600" width="2680" height="105" class="lane"/>
- <text x="86" y="1638" class="layer-title">L6|数据与可靠性底座</text>
- <text x="86" y="1664" class="layer-note">单库强一致 + Outbox 可靠异步;账本只追加,审计可追溯</text>
- <!-- helper function visually via manually placed boxes -->
- <!-- L0 boxes -->
- <g>
- <rect x="390" y="190" width="250" height="82" class="external"/><text x="414" y="220" class="box-title">患者端</text><text x="414" y="248" class="box-sub">小程序 / APP / 公众号</text>
- <rect x="670" y="190" width="250" height="82" class="external"/><text x="694" y="220" class="box-title">医护端</text><text x="694" y="248" class="box-sub">医生站 / 护士站 / PDA</text>
- <rect x="950" y="190" width="250" height="82" class="external"/><text x="974" y="220" class="box-title">机器人 / 自助机</text><text x="974" y="248" class="box-sub">床旁屏 / 院内终端</text>
- <rect x="1230" y="190" width="250" height="82" class="external"/><text x="1254" y="220" class="box-title">运营 / 财务</text><text x="1254" y="248" class="box-sub">医院管理员 / 医梦运营</text>
- <rect x="1510" y="190" width="250" height="82" class="external"/><text x="1534" y="220" class="box-title">IoMT 设备</text><text x="1534" y="248" class="box-sub">体征 / 床垫 / 输液</text>
- <rect x="1790" y="190" width="250" height="82" class="external"/><text x="1814" y="220" class="box-title">语音网关</text><text x="1814" y="248" class="box-sub">外呼 / 通话回调</text>
- </g>
- <!-- L1 boxes -->
- <g>
- <rect x="420" y="380" width="360" height="86" class="entry"/><text x="444" y="412" class="box-title">emoon-openplatform</text><text x="444" y="441" class="box-sub">对外 API / 签名鉴权 / Agent / SSE / Card Action</text>
- <rect x="820" y="380" width="360" height="86" class="entry"/><text x="844" y="412" class="box-title">emoon-admin</text><text x="844" y="441" class="box-sub">管理后台 / 合同账单 / 配置 / 审计运营</text>
- <rect x="1220" y="380" width="330" height="86" class="current"/><text x="1244" y="412" class="box-title">snailjob-server</text><text x="1244" y="441" class="box-sub">Outbox / 账单 / 随访 / 巡检任务</text>
- <rect x="1590" y="380" width="330" height="86" class="current"/><text x="1614" y="412" class="box-title">monitor-admin</text><text x="1614" y="441" class="box-sub">运行监控 / 告警 / 任务观测</text>
- </g>
- <!-- L2 current boxes -->
- <g>
- <rect x="210" y="610" width="310" height="95" class="common"/><text x="232" y="642" class="box-title">emoon-common</text><text x="232" y="670" class="box-sub">core / redis / mybatis / security</text><text x="232" y="693" class="mini">tenant / sse / websocket / idempotent</text>
- <rect x="560" y="610" width="310" height="95" class="current"/><text x="582" y="642" class="box-title">emoon-system-api</text><text x="582" y="670" class="box-sub">系统 DO / Service API / Mapper</text><text x="582" y="693" class="mini">项目 / 租户 / 用户 / 配置</text>
- <rect x="910" y="600" width="360" height="115" class="legacy"/><text x="932" y="632" class="box-title">emoon-mcp-api(待拆)</text><text x="932" y="660" class="box-sub">当前混合:AgentEngine / Conversation</text><text x="932" y="683" class="box-sub">CardInstance / HospitalActivity / Mapper</text><text x="932" y="706" class="mini">问题:Agent、Card、MCP 概念边界混杂</text>
- <rect x="1310" y="610" width="310" height="95" class="current"/><text x="1332" y="642" class="box-title">emoon-knowledge-api</text><text x="1332" y="670" class="box-sub">知识库 / Agent 设计态 / 质控资产</text>
- <rect x="1660" y="610" width="310" height="95" class="current"/><text x="1682" y="642" class="box-title">emoon-system</text><text x="1682" y="670" class="box-sub">系统管理 / 引擎配置 CRUD</text>
- <rect x="2010" y="610" width="310" height="95" class="current"/><text x="2032" y="642" class="box-title">emoon-mcp</text><text x="2032" y="670" class="box-sub">当前 MCP 雏形 / 模板代码</text>
- <rect x="2360" y="610" width="250" height="95" class="current"/><text x="2382" y="642" class="box-title">emoon-tongue</text><text x="2382" y="670" class="box-sub">舌诊 / 面诊专精能力</text>
- </g>
- <!-- L3 split target api -->
- <g>
- <rect x="170" y="875" width="340" height="92" class="planned"/><text x="192" y="907" class="box-title">emoon-ai-agent-api</text><text x="192" y="935" class="box-sub">AgentEngine / AgentRequest</text><text x="192" y="958" class="mini">Dify / DirectLLM / Mock 接口</text>
- <rect x="540" y="875" width="340" height="92" class="planned"/><text x="562" y="907" class="box-title">emoon-ai-card-api</text><text x="562" y="935" class="box-sub">CardDefinition / Instance / Action</text><text x="562" y="958" class="mini">卡片状态机 / 快照 / 动作契约</text>
- <rect x="910" y="875" width="340" height="92" class="planned"/><text x="932" y="907" class="box-title">emoon-ai-mcp-api</text><text x="932" y="935" class="box-sub">ToolContract / ToolResult</text><text x="932" y="958" class="mini">HospitalAdapter SPI / 工具审计</text>
- <rect x="1280" y="875" width="340" height="92" class="planned"/><text x="1302" y="907" class="box-title">emoon-ai-meter-api</text><text x="1302" y="935" class="box-sub">MeterEvent / BillingEpisode</text><text x="1302" y="958" class="mini">Outbox Contract / 事件归并</text>
- <rect x="1650" y="875" width="340" height="92" class="planned"/><text x="1672" y="907" class="box-title">emoon-ai-billing-api</text><text x="1672" y="935" class="box-sub">Contract / Pricing / Credit</text><text x="1672" y="958" class="mini">账本 / 账单 / 分摊契约</text>
- <rect x="2020" y="875" width="340" height="92" class="planned"/><text x="2042" y="907" class="box-title">ai-knowledge-api</text><text x="2042" y="935" class="box-sub">Knowledge / Prompt / RAG / QC</text><text x="2042" y="958" class="mini">知识版本 / 引用 / 质控规则</text>
- </g>
- <!-- L3 impl -->
- <g>
- <rect x="170" y="1015" width="340" height="92" class="impl"/><text x="192" y="1047" class="box-title">emoon-ai-agent</text><text x="192" y="1075" class="box-sub">Dify 适配 / DirectLLM / 会话编排</text>
- <rect x="540" y="1015" width="340" height="92" class="impl"/><text x="562" y="1047" class="box-title">emoon-ai-card</text><text x="562" y="1075" class="box-sub">卡片定义 / 实例 / 动作闭环</text>
- <rect x="910" y="1015" width="340" height="92" class="impl"/><text x="932" y="1047" class="box-title">emoon-ai-mcp</text><text x="932" y="1075" class="box-sub">MCP 工具 / HIS Adapter / 熔断</text>
- <rect x="1280" y="1015" width="340" height="92" class="impl"/><text x="1302" y="1047" class="box-title">emoon-ai-meter</text><text x="1302" y="1075" class="box-sub">Outbox / MeterEvent / Episode</text>
- <rect x="1650" y="1015" width="340" height="92" class="impl"/><text x="1672" y="1047" class="box-title">emoon-ai-billing</text><text x="1672" y="1075" class="box-sub">合同 / 能力值 / 定价 / 账单</text>
- <rect x="2020" y="1015" width="340" height="92" class="impl"/><text x="2042" y="1047" class="box-title">ai-knowledge</text><text x="2042" y="1075" class="box-sub">知识资产 / Prompt / RAG / 质控</text>
- </g>
- <!-- L4 future -->
- <g>
- <rect x="270" y="1260" width="360" height="86" class="future"/><text x="292" y="1292" class="box-title">MCP Tool Server</text><text x="292" y="1320" class="box-sub">院内部署 / HIS 工具网关</text>
- <rect x="680" y="1260" width="360" height="86" class="future"/><text x="702" y="1292" class="box-title">AudioStreamGateway</text><text x="702" y="1320" class="box-sub">WebSocket 音频 / ASR 分钟</text>
- <rect x="1090" y="1260" width="360" height="86" class="future"/><text x="1112" y="1292" class="box-title">IoMTEventIngestion</text><text x="1112" y="1320" class="box-sub">设备认证 / 护理预警事件</text>
- <rect x="1500" y="1260" width="360" height="86" class="future"/><text x="1522" y="1292" class="box-title">OutboundFollowup</text><text x="1522" y="1320" class="box-sub">外呼随访 / 风险升级</text>
- <rect x="1910" y="1260" width="360" height="86" class="future"/><text x="1932" y="1292" class="box-title">File/OCR/ASR Worker</text><text x="1932" y="1320" class="box-sub">报告解析 / 图片 / 长任务</text>
- </g>
- <!-- L5 external -->
- <g>
- <rect x="350" y="1495" width="360" height="62" class="external"/><text x="374" y="1528" class="box-title">Dify Platform</text><text x="374" y="1549" class="mini">Workflow / LLM / Tool Call</text>
- <rect x="760" y="1495" width="360" height="62" class="external"/><text x="784" y="1528" class="box-title">DirectLLM / Vision</text><text x="784" y="1549" class="mini">L1 主引擎 / 图像模型 / 降级</text>
- <rect x="1170" y="1495" width="390" height="62" class="external"/><text x="1194" y="1528" class="box-title">HIS / EMR / LIS / PACS</text><text x="1194" y="1549" class="mini">号源 / 建档 / 住院 / 报告</text>
- <rect x="1610" y="1495" width="330" height="62" class="external"/><text x="1634" y="1528" class="box-title">ASR / TTS Provider</text><text x="1634" y="1549" class="mini">转写 / 合成 / 电话语音</text>
- <rect x="1990" y="1495" width="330" height="62" class="external"/><text x="2014" y="1528" class="box-title">Object Storage</text><text x="2014" y="1549" class="mini">图片 / 报告 / 音频 / 附件</text>
- </g>
- <!-- L6 data -->
- <g>
- <rect x="330" y="1645" width="330" height="45" class="data"/><text x="354" y="1674" class="box-title">MySQL 单库强一致</text>
- <rect x="710" y="1645" width="330" height="45" class="data"/><text x="734" y="1674" class="box-title">Redis 缓存 / 短锁</text>
- <rect x="1090" y="1645" width="330" height="45" class="data"/><text x="1114" y="1674" class="box-title">Outbox 可靠事件</text>
- <rect x="1470" y="1645" width="330" height="45" class="data"/><text x="1494" y="1674" class="box-title">Credit Ledger 账本</text>
- <rect x="1850" y="1645" width="330" height="45" class="data"/><text x="1874" y="1674" class="box-title">Audit / Trace 审计</text>
- </g>
- <!-- arrows L0 to L1 -->
- <path d="M515 272 C515 320, 520 342, 550 378" class="call"/>
- <path d="M795 272 C760 320, 700 342, 650 378" class="call"/>
- <path d="M1075 272 C980 322, 840 350, 770 380" class="call"/>
- <path d="M1355 272 C1300 320, 1140 350, 1040 380" class="call"/>
- <path d="M1635 272 C1550 650, 1370 1000, 1270 1255" class="event"/>
- <path d="M1915 272 C1850 640, 1700 1030, 1680 1255" class="event"/>
- <!-- L1 to L2/L3 -->
- <path d="M600 466 C600 530, 790 560, 950 600" class="call"/>
- <path d="M1000 466 C1100 530, 1300 565, 1480 610" class="call"/>
- <path d="M1385 466 C1420 540, 1440 760, 1450 1010" class="event"/>
- <!-- legacy split arrows -->
- <path d="M1030 715 C850 760, 510 800, 360 870" class="split"/>
- <path d="M1080 715 C900 770, 760 805, 710 870" class="split"/>
- <path d="M1130 715 C1080 765, 1040 810, 1080 870" class="split"/>
- <!-- API to impl vertical -->
- <path d="M340 967 L340 1010" class="call thin"/>
- <path d="M710 967 L710 1010" class="call thin"/>
- <path d="M1080 967 L1080 1010" class="call thin"/>
- <path d="M1450 967 L1450 1010" class="call thin"/>
- <path d="M1820 967 L1820 1010" class="call thin"/>
- <path d="M2190 967 L2190 1010" class="call thin"/>
- <!-- domain dependencies -->
- <path d="M510 1060 L535 1060" class="call thin"/>
- <path d="M880 1060 L905 1060" class="call thin"/>
- <path d="M1250 1060 L1275 1060" class="event thin"/>
- <path d="M1620 1060 L1645 1060" class="call thin"/>
- <path d="M1990 1060 L2015 1060" class="call thin"/>
- <path d="M1450 1107 C1450 1135, 1730 1135, 1820 1107" class="event thin"/>
- <!-- future service arrows -->
- <path d="M1080 1107 C920 1160, 620 1190, 450 1255" class="split"/>
- <path d="M340 1107 C470 1160, 700 1190, 860 1255" class="split"/>
- <path d="M1450 1107 C1420 1170, 1300 1205, 1270 1255" class="event"/>
- <path d="M1450 1107 C1500 1170, 1660 1200, 1680 1255" class="event"/>
- <path d="M2190 1107 C2120 1170, 2070 1210, 2090 1255" class="split"/>
- <!-- external system arrows -->
- <path d="M340 1107 C360 1260, 450 1390, 510 1490" class="call"/>
- <path d="M340 1107 C430 1260, 690 1390, 900 1490" class="call"/>
- <path d="M1080 1107 C1130 1260, 1230 1390, 1350 1490" class="call"/>
- <path d="M860 1346 C960 1410, 1450 1450, 1760 1490" class="call"/>
- <path d="M1680 1346 C1700 1410, 1740 1450, 1760 1490" class="call"/>
- <path d="M2090 1346 C2090 1410, 2120 1450, 2155 1490" class="call"/>
- <!-- data arrows -->
- <path d="M1450 1107 C1410 1290, 1250 1510, 1250 1640" class="event"/>
- <path d="M1820 1107 C1780 1290, 1640 1510, 1635 1640" class="event"/>
- <path d="M600 466 C600 900, 500 1350, 495 1640" class="call thin"/>
- <path d="M710 1107 C720 1290, 780 1510, 875 1640" class="call thin"/>
- <path d="M1080 1107 C1180 1290, 1850 1510, 2015 1640" class="event thin"/>
- <!-- callouts -->
- <rect x="2380" y="875" width="300" height="232" rx="18" fill="#fff" stroke="#0f172a" stroke-width="1.5" filter="url(#shadow)"/>
- <text x="2404" y="910" class="box-title">拆分口径</text>
- <text x="2404" y="944" class="box-sub">1. emoon-ai-agent-api:会话与引擎</text>
- <text x="2404" y="974" class="box-sub">2. emoon-ai-card-api:卡片与动作</text>
- <text x="2404" y="1004" class="box-sub">3. emoon-ai-mcp-api:工具与 HIS</text>
- <text x="2404" y="1034" class="box-sub">4. emoon-ai-meter:事件归并</text>
- <text x="2404" y="1064" class="box-sub">5. emoon-ai-billing:合同账本</text>
- <rect x="2320" y="1260" width="360" height="86" rx="18" fill="#fff7ed" stroke="#fb923c" stroke-width="2" filter="url(#shadow)"/>
- <text x="2344" y="1293" class="box-title">3 人团队建议</text>
- <text x="2344" y="1322" class="box-sub">先模块化单体;MCP/音频/IoMT/外呼</text>
- <text x="2344" y="1344" class="box-sub">有部署压力后再独立服务化。</text>
- </svg>
|