273 lines
20 KiB
HTML
273 lines
20 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>fumamxCRM - System Architecture</title>
|
|
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
<style>
|
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
body {
|
|
font-family: 'JetBrains Mono', monospace;
|
|
background: #020617;
|
|
min-height: 100vh;
|
|
padding: 2rem;
|
|
color: white;
|
|
}
|
|
.container { max-width: 1200px; margin: 0 auto; }
|
|
.header { margin-bottom: 2rem; }
|
|
.header-row { display: flex; align-items: center; gap: 1rem; margin-bottom: 0.5rem; }
|
|
.pulse-dot {
|
|
width: 12px; height: 12px; background: #22d3ee; border-radius: 50%;
|
|
animation: pulse 2s infinite;
|
|
}
|
|
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }
|
|
h1 { font-size: 1.5rem; font-weight: 700; letter-spacing: -0.025em; }
|
|
.subtitle { color: #94a3b8; font-size: 0.875rem; margin-left: 1.75rem; }
|
|
.diagram-container {
|
|
background: rgba(15, 23, 42, 0.5); border-radius: 1rem;
|
|
border: 1px solid #1e293b; padding: 1.5rem; overflow-x: auto;
|
|
}
|
|
svg { width: 100%; min-width: 900px; display: block; }
|
|
.cards {
|
|
display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
|
gap: 1rem; margin-top: 2rem;
|
|
}
|
|
.card {
|
|
background: rgba(15, 23, 42, 0.5); border-radius: 0.75rem;
|
|
border: 1px solid #1e293b; padding: 1.25rem;
|
|
}
|
|
.card-header { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.75rem; }
|
|
.card-dot { width: 8px; height: 8px; border-radius: 50%; }
|
|
.card h3 { font-size: 0.875rem; font-weight: 600; color: #e2e8f0; }
|
|
.card ul { list-style: none; font-size: 0.75rem; color: #94a3b8; line-height: 1.8; }
|
|
.card li::before { content: "• "; color: #64748b; }
|
|
.footer {
|
|
margin-top: 2rem; padding-top: 1rem; border-top: 1px solid #1e293b;
|
|
font-size: 0.75rem; color: #64748b; text-align: center;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<div class="header">
|
|
<div class="header-row">
|
|
<div class="pulse-dot"></div>
|
|
<h1>fumamxCRM - System Architecture</h1>
|
|
</div>
|
|
<div class="subtitle">系统架构图 · Hand-Drawn SVG</div>
|
|
</div>
|
|
<div class="diagram-container">
|
|
<svg viewBox="0 0 1100 740" xmlns="http://www.w3.org/2000/svg">
|
|
<defs>
|
|
<pattern id="grid" width="40" height="40" patternUnits="userSpaceOnUse">
|
|
<path d="M 40 0 L 0 0 0 40" fill="none" stroke="#1e293b" stroke-width="0.5"/>
|
|
</pattern>
|
|
<filter id="dropShadow" x="-50%" y="-50%" width="200%" height="200%">
|
|
<feDropShadow dx="0" dy="2" stdDeviation="3" flood-opacity="0.3"/>
|
|
</filter>
|
|
<marker id="arrowhead" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
|
|
<polygon points="0 0, 10 3.5, 0 7" fill="#64748b"/>
|
|
</marker>
|
|
<marker id="arrowhead-cyan" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
|
|
<polygon points="0 0, 10 3.5, 0 7" fill="#22d3ee"/>
|
|
</marker>
|
|
<marker id="arrowhead-green" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
|
|
<polygon points="0 0, 10 3.5, 0 7" fill="#34d399"/>
|
|
</marker>
|
|
<marker id="arrowhead-rose" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
|
|
<polygon points="0 0, 10 3.5, 0 7" fill="#fb7185"/>
|
|
</marker>
|
|
<marker id="arrowhead-amber" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
|
|
<polygon points="0 0, 10 3.5, 0 7" fill="#fbbf24"/>
|
|
</marker>
|
|
<marker id="arrowhead-purple" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
|
|
<polygon points="0 0, 10 3.5, 0 7" fill="#a78bfa"/>
|
|
</marker>
|
|
</defs>
|
|
<rect width="1100" height="740" fill="url(#grid)"/>
|
|
<rect x="40" y="30" width="780" height="560" rx="10" fill="rgba(15, 23, 42, 0.3)" stroke="#94a3b8" stroke-width="1.5" stroke-dasharray="5,3"/>
|
|
<rect x="55" y="22" width="138" height="16" fill="#0f172a"/>
|
|
<text x="124" y="33" fill="#94a3b8" font-size="9" font-weight="500" text-anchor="middle">fumamxCRM System</text>
|
|
<rect x="60" y="50" width="180" height="100" rx="10" fill="rgba(15, 23, 42, 0.3)" stroke="#22d3ee" stroke-width="1.5" stroke-dasharray="5,3"/>
|
|
<rect x="75" y="42" width="122" height="16" fill="#0f172a"/>
|
|
<text x="136" y="53" fill="#22d3ee" font-size="9" font-weight="500" text-anchor="middle">Frontend Layer</text>
|
|
<rect x="280" y="50" width="350" height="100" rx="10" fill="rgba(15, 23, 42, 0.3)" stroke="#34d399" stroke-width="1.5" stroke-dasharray="5,3"/>
|
|
<rect x="295" y="42" width="98" height="16" fill="#0f172a"/>
|
|
<text x="344" y="53" fill="#34d399" font-size="9" font-weight="500" text-anchor="middle">API Gateway</text>
|
|
<rect x="60" y="160" width="740" height="110" rx="10" fill="rgba(15, 23, 42, 0.3)" stroke="#34d399" stroke-width="1.5" stroke-dasharray="5,3"/>
|
|
<rect x="75" y="152" width="130" height="16" fill="#0f172a"/>
|
|
<text x="140" y="163" fill="#34d399" font-size="9" font-weight="500" text-anchor="middle">FastAPI Backend</text>
|
|
<rect x="180" y="460" width="500" height="110" rx="10" fill="rgba(15, 23, 42, 0.3)" stroke="#a78bfa" stroke-width="1.5" stroke-dasharray="5,3"/>
|
|
<rect x="195" y="452" width="90" height="16" fill="#0f172a"/>
|
|
<text x="240" y="463" fill="#a78bfa" font-size="9" font-weight="500" text-anchor="middle">Data Layer</text>
|
|
<rect x="80" y="60" width="140" height="49" rx="6" fill="#0f172a" stroke="#22d3ee" stroke-width="1.5" opacity="1.0"/>
|
|
<rect x="80" y="60" width="140" height="49" rx="6" fill="rgba(8, 51, 68, 0.4)" stroke="#22d3ee" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="150" y="78" fill="white" font-size="11" font-weight="600" text-anchor="middle">React Frontend</text>
|
|
<text x="150" y="92" fill="#94a3b8" font-size="8" font-weight="normal" text-anchor="middle">Port 8888</text>
|
|
<text x="150" y="106" fill="#cbd5e1" font-size="8" font-weight="normal" text-anchor="middle">SPA / React Router
|
|
Axios / State</text>
|
|
<rect x="300" y="60" width="130" height="49" rx="6" fill="#0f172a" stroke="#fb7185" stroke-width="1.5" opacity="1.0"/>
|
|
<rect x="300" y="60" width="130" height="49" rx="6" fill="rgba(136, 19, 55, 0.4)" stroke="#fb7185" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="365" y="78" fill="white" font-size="11" font-weight="600" text-anchor="middle">Auth Middleware</text>
|
|
<text x="365" y="92" fill="#cbd5e1" font-size="8" font-weight="normal" text-anchor="middle">JWT Verify
|
|
Session Check</text>
|
|
<rect x="480" y="60" width="130" height="49" rx="6" fill="#0f172a" stroke="#34d399" stroke-width="1.5" opacity="1.0"/>
|
|
<rect x="480" y="60" width="130" height="49" rx="6" fill="rgba(6, 78, 59, 0.4)" stroke="#34d399" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="545" y="78" fill="white" font-size="11" font-weight="600" text-anchor="middle">CORS / Rate Limit</text>
|
|
<text x="545" y="92" fill="#cbd5e1" font-size="8" font-weight="normal" text-anchor="middle">跨域 / 限流
|
|
Error Handler</text>
|
|
<rect x="80" y="180" width="140" height="49" rx="6" fill="#0f172a" stroke="#34d399" stroke-width="1.5" opacity="1.0"/>
|
|
<rect x="80" y="180" width="140" height="49" rx="6" fill="rgba(6, 78, 59, 0.4)" stroke="#34d399" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="150" y="198" fill="white" font-size="11" font-weight="600" text-anchor="middle">FastAPI Core</text>
|
|
<text x="150" y="212" fill="#94a3b8" font-size="8" font-weight="normal" text-anchor="middle">Port 8889</text>
|
|
<text x="150" y="226" fill="#cbd5e1" font-size="8" font-weight="normal" text-anchor="middle">Routers / Dependencies
|
|
Pydantic Models</text>
|
|
<rect x="300" y="180" width="130" height="49" rx="6" fill="#0f172a" stroke="#fb7185" stroke-width="1.5" opacity="1.0"/>
|
|
<rect x="300" y="180" width="130" height="49" rx="6" fill="rgba(136, 19, 55, 0.4)" stroke="#fb7185" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="365" y="198" fill="white" font-size="11" font-weight="600" text-anchor="middle">Auth Service</text>
|
|
<text x="365" y="212" fill="#cbd5e1" font-size="8" font-weight="normal" text-anchor="middle">Login / Register / Logout
|
|
Token Refresh</text>
|
|
<rect x="480" y="180" width="130" height="49" rx="6" fill="#0f172a" stroke="#34d399" stroke-width="1.5" opacity="1.0"/>
|
|
<rect x="480" y="180" width="130" height="49" rx="6" fill="rgba(6, 78, 59, 0.4)" stroke="#34d399" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="545" y="198" fill="white" font-size="11" font-weight="600" text-anchor="middle">Article API</text>
|
|
<text x="545" y="212" fill="#cbd5e1" font-size="8" font-weight="normal" text-anchor="middle">CRUD / Search
|
|
Category Filter</text>
|
|
<rect x="660" y="180" width="120" height="49" rx="6" fill="#0f172a" stroke="#34d399" stroke-width="1.5" opacity="1.0"/>
|
|
<rect x="660" y="180" width="120" height="49" rx="6" fill="rgba(6, 78, 59, 0.4)" stroke="#34d399" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="720" y="198" fill="white" font-size="11" font-weight="600" text-anchor="middle">User API</text>
|
|
<text x="720" y="212" fill="#cbd5e1" font-size="8" font-weight="normal" text-anchor="middle">Profile / Settings
|
|
Permission</text>
|
|
<rect x="80" y="320" width="110" height="49" rx="6" fill="#0f172a" stroke="#34d399" stroke-width="1.5" opacity="1.0"/>
|
|
<rect x="80" y="320" width="110" height="49" rx="6" fill="rgba(6, 78, 59, 0.4)" stroke="#34d399" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="135" y="338" fill="white" font-size="11" font-weight="600" text-anchor="middle">Pydantic</text>
|
|
<text x="135" y="352" fill="#cbd5e1" font-size="8" font-weight="normal" text-anchor="middle">Data Validation
|
|
Schema</text>
|
|
<rect x="240" y="320" width="110" height="49" rx="6" fill="#0f172a" stroke="#fb7185" stroke-width="1.5" opacity="1.0"/>
|
|
<rect x="240" y="320" width="110" height="49" rx="6" fill="rgba(136, 19, 55, 0.4)" stroke="#fb7185" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="295" y="338" fill="white" font-size="11" font-weight="600" text-anchor="middle">JWT Auth</text>
|
|
<text x="295" y="352" fill="#cbd5e1" font-size="8" font-weight="normal" text-anchor="middle">Token Generate
|
|
Token Verify</text>
|
|
<rect x="400" y="320" width="120" height="49" rx="6" fill="#0f172a" stroke="#fbbf24" stroke-width="1.5" opacity="1.0"/>
|
|
<rect x="400" y="320" width="120" height="49" rx="6" fill="rgba(120, 53, 15, 0.3)" stroke="#fbbf24" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="460" y="338" fill="white" font-size="11" font-weight="600" text-anchor="middle">fumamxAuth</text>
|
|
<text x="460" y="352" fill="#cbd5e1" font-size="8" font-weight="normal" text-anchor="middle">External OAuth
|
|
User Info</text>
|
|
<rect x="560" y="320" width="120" height="49" rx="6" fill="#0f172a" stroke="#34d399" stroke-width="1.5" opacity="1.0"/>
|
|
<rect x="560" y="320" width="120" height="49" rx="6" fill="rgba(6, 78, 59, 0.4)" stroke="#34d399" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="620" y="338" fill="white" font-size="11" font-weight="600" text-anchor="middle">SQLAlchemy</text>
|
|
<text x="620" y="352" fill="#cbd5e1" font-size="8" font-weight="normal" text-anchor="middle">ORM / Models
|
|
Query Builder</text>
|
|
<rect x="200" y="480" width="120" height="49" rx="6" fill="#0f172a" stroke="#a78bfa" stroke-width="1.5" opacity="1.0"/>
|
|
<rect x="200" y="480" width="120" height="49" rx="6" fill="rgba(76, 29, 149, 0.4)" stroke="#a78bfa" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="260" y="498" fill="white" font-size="11" font-weight="600" text-anchor="middle">SQLite</text>
|
|
<text x="260" y="512" fill="#94a3b8" font-size="8" font-weight="normal" text-anchor="middle">Main DB</text>
|
|
<text x="260" y="526" fill="#cbd5e1" font-size="8" font-weight="normal" text-anchor="middle">users / articles
|
|
logs / config</text>
|
|
<rect x="380" y="480" width="100" height="49" rx="6" fill="#0f172a" stroke="#a78bfa" stroke-width="1.5" opacity="1.0"/>
|
|
<rect x="380" y="480" width="100" height="49" rx="6" fill="rgba(76, 29, 149, 0.4)" stroke="#a78bfa" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="430" y="498" fill="white" font-size="11" font-weight="600" text-anchor="middle">Redis</text>
|
|
<text x="430" y="512" fill="#94a3b8" font-size="8" font-weight="normal" text-anchor="middle">Cache</text>
|
|
<text x="430" y="526" fill="#cbd5e1" font-size="8" font-weight="normal" text-anchor="middle">Session Store
|
|
Token Blacklist</text>
|
|
<rect x="540" y="480" width="110" height="49" rx="6" fill="#0f172a" stroke="#94a3b8" stroke-width="1.5" opacity="1.0"/>
|
|
<rect x="540" y="480" width="110" height="49" rx="6" fill="rgba(30, 41, 59, 0.5)" stroke="#94a3b8" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="595" y="498" fill="white" font-size="11" font-weight="600" text-anchor="middle">Local File</text>
|
|
<text x="595" y="512" fill="#94a3b8" font-size="8" font-weight="normal" text-anchor="middle">Storage</text>
|
|
<text x="595" y="526" fill="#cbd5e1" font-size="8" font-weight="normal" text-anchor="middle">Uploads / Static
|
|
Logs</text>
|
|
<line x1="220" y1="95" x2="300" y2="90" stroke="#64748b" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<rect x="222" y="84" width="77" height="14" fill="#0f172a" rx="2"/>
|
|
<text x="260" y="95" fill="#64748b" font-size="8" font-weight="normal" text-anchor="middle">API Request</text>
|
|
<line x1="220" y1="95" x2="480" y2="90" stroke="#64748b" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<line x1="365" y1="120" x2="150" y2="180" stroke="#64748b" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<line x1="545" y1="120" x2="365" y2="180" stroke="#64748b" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<line x1="220" y1="215" x2="300" y2="215" stroke="#fb7185" stroke-width="1.5" stroke-dasharray="5,3" marker-end="url(#arrowhead-rose)"/>
|
|
<rect x="225" y="207" width="70" height="14" fill="#0f172a" rx="2"/>
|
|
<text x="260" y="218" fill="#fb7185" font-size="8" font-weight="normal" text-anchor="middle">auth check</text>
|
|
<line x1="220" y1="215" x2="480" y2="215" stroke="#64748b" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<line x1="220" y1="215" x2="660" y2="215" stroke="#64748b" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<line x1="150" y1="250" x2="135" y2="320" stroke="#64748b" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<rect x="114" y="277" width="56" height="14" fill="#0f172a" rx="2"/>
|
|
<text x="142" y="288" fill="#64748b" font-size="8" font-weight="normal" text-anchor="middle">validate</text>
|
|
<line x1="365" y1="250" x2="295" y2="320" stroke="#fb7185" stroke-width="1.5" stroke-dasharray="5,3" marker-end="url(#arrowhead-rose)"/>
|
|
<rect x="302" y="277" width="56" height="14" fill="#0f172a" rx="2"/>
|
|
<text x="330" y="288" fill="#fb7185" font-size="8" font-weight="normal" text-anchor="middle">generate</text>
|
|
<line x1="365" y1="250" x2="460" y2="320" stroke="#fb7185" stroke-width="1.5" stroke-dasharray="5,3" marker-end="url(#arrowhead-rose)"/>
|
|
<rect x="374" y="277" width="77" height="14" fill="#0f172a" rx="2"/>
|
|
<text x="412" y="288" fill="#fb7185" font-size="8" font-weight="normal" text-anchor="middle">OAuth2 flow</text>
|
|
<line x1="545" y1="250" x2="620" y2="320" stroke="#64748b" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<line x1="720" y1="250" x2="620" y2="320" stroke="#64748b" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<line x1="135" y1="380" x2="260" y2="480" stroke="#64748b" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<rect x="152" y="422" width="91" height="14" fill="#0f172a" rx="2"/>
|
|
<text x="197" y="433" fill="#64748b" font-size="8" font-weight="normal" text-anchor="middle">insert/update</text>
|
|
<line x1="295" y1="380" x2="430" y2="480" stroke="#fb7185" stroke-width="1.5" stroke-dasharray="5,3" marker-end="url(#arrowhead-rose)"/>
|
|
<rect x="331" y="422" width="63" height="14" fill="#0f172a" rx="2"/>
|
|
<text x="362" y="433" fill="#fb7185" font-size="8" font-weight="normal" text-anchor="middle">token TTL</text>
|
|
<line x1="400" y1="350" x2="350" y2="350" stroke="#fb7185" stroke-width="1.5" stroke-dasharray="5,3" marker-end="url(#arrowhead-rose)"/>
|
|
<rect x="333" y="342" width="84" height="14" fill="#0f172a" rx="2"/>
|
|
<text x="375" y="353" fill="#fb7185" font-size="8" font-weight="normal" text-anchor="middle">verify token</text>
|
|
<line x1="620" y1="380" x2="260" y2="480" stroke="#64748b" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<rect x="402" y="422" width="77" height="14" fill="#0f172a" rx="2"/>
|
|
<text x="440" y="433" fill="#64748b" font-size="8" font-weight="normal" text-anchor="middle">SQL queries</text>
|
|
<line x1="380" y1="510" x2="320" y2="515" stroke="#fbbf24" stroke-width="1.5" stroke-dasharray="2,2" marker-end="url(#arrowhead-amber)"/>
|
|
<rect x="315" y="504" width="70" height="14" fill="#0f172a" rx="2"/>
|
|
<text x="350" y="515" fill="#fbbf24" font-size="8" font-weight="normal" text-anchor="middle">sync cache</text>
|
|
<rect x="30" y="670" width="850" height="60" rx="6" fill="rgba(15, 23, 42, 0.8)" stroke="#1e293b" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="45" y="690" fill="#64748b" font-size="10" font-weight="normal" text-anchor="start">组件类型:</text>
|
|
<rect x="120" y="678" width="16" height="16" rx="3" fill="rgba(8, 51, 68, 0.4)" stroke="#22d3ee" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="142" y="690" fill="#94a3b8" font-size="9" font-weight="normal" text-anchor="start">前端</text>
|
|
<rect x="195" y="678" width="16" height="16" rx="3" fill="rgba(6, 78, 59, 0.4)" stroke="#34d399" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="217" y="690" fill="#94a3b8" font-size="9" font-weight="normal" text-anchor="start">后端</text>
|
|
<rect x="270" y="678" width="16" height="16" rx="3" fill="rgba(76, 29, 149, 0.4)" stroke="#a78bfa" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="292" y="690" fill="#94a3b8" font-size="9" font-weight="normal" text-anchor="start">数据库</text>
|
|
<rect x="345" y="678" width="16" height="16" rx="3" fill="rgba(120, 53, 15, 0.3)" stroke="#fbbf24" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="367" y="690" fill="#94a3b8" font-size="9" font-weight="normal" text-anchor="start">外部API</text>
|
|
<rect x="420" y="678" width="16" height="16" rx="3" fill="rgba(136, 19, 55, 0.4)" stroke="#fb7185" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="442" y="690" fill="#94a3b8" font-size="9" font-weight="normal" text-anchor="start">认证</text>
|
|
<rect x="495" y="678" width="16" height="16" rx="3" fill="rgba(30, 41, 59, 0.5)" stroke="#94a3b8" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="517" y="690" fill="#94a3b8" font-size="9" font-weight="normal" text-anchor="start">通用</text>
|
|
<text x="45" y="715" fill="#64748b" font-size="10" font-weight="normal" text-anchor="start">连接类型:</text>
|
|
<line x1="120" y1="710" x2="140" y2="710" stroke="#64748b" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<text x="148" y="714" fill="#94a3b8" font-size="9" font-weight="normal" text-anchor="start">数据流</text>
|
|
<line x1="195" y1="710" x2="215" y2="710" stroke="#fb7185" stroke-width="1.5" marker-end="url(#arrowhead-rose)"/>
|
|
<text x="223" y="714" fill="#94a3b8" font-size="9" font-weight="normal" text-anchor="start">认证流</text>
|
|
<line x1="270" y1="710" x2="290" y2="710" stroke="#fbbf24" stroke-width="1.5" marker-end="url(#arrowhead-amber)"/>
|
|
<text x="298" y="714" fill="#94a3b8" font-size="9" font-weight="normal" text-anchor="start">配置</text>
|
|
</svg>
|
|
</div>
|
|
<div class="cards">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<div class="card-dot" style="background: #94a3b8;"></div>
|
|
<h3>Frontend</h3>
|
|
</div>
|
|
<ul></ul>
|
|
</div>
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<div class="card-dot" style="background: #94a3b8;"></div>
|
|
<h3>Backend</h3>
|
|
</div>
|
|
<ul></ul>
|
|
</div>
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<div class="card-dot" style="background: #94a3b8;"></div>
|
|
<h3>Security</h3>
|
|
</div>
|
|
<ul></ul>
|
|
</div>
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<div class="card-dot" style="background: #94a3b8;"></div>
|
|
<h3>Database</h3>
|
|
</div>
|
|
<ul></ul>
|
|
</div></div>
|
|
<div class="footer">
|
|
生成时间: 2026-04-18 11:02 | Hand-Drawn Diagram · Zero Token Cost
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html> |