269 lines
23 KiB
HTML
269 lines
23 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>Personal Blog 技术架构图</title>
|
|
<style>
|
|
body {
|
|
margin: 0;
|
|
background: #020617;
|
|
font-family: 'Noto Sans Mono CJK SC', 'JetBrains Mono', 'WenQuanYi Zen Hei Mono', monospace;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
min-height: 100vh;
|
|
}
|
|
h1 {
|
|
color: #e2e8f0;
|
|
margin: 24px 0 6px;
|
|
font-size: 24px;
|
|
}
|
|
h2 {
|
|
color: #64748b;
|
|
margin: 0 0 20px;
|
|
font-size: 14px;
|
|
font-weight: normal;
|
|
}
|
|
#diagram {
|
|
width: 98vw;
|
|
overflow: auto;
|
|
padding-bottom: 40px;
|
|
}
|
|
.info {
|
|
color: #475569;
|
|
font-size: 12px;
|
|
margin-top: 16px;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<h1>📝 Personal Blog 技术架构图</h1>
|
|
<h2>FastAPI + React + SQLite | 手绘风格 SVG | 零 AI Token 成本</h2>
|
|
<div id="diagram">
|
|
<svg viewBox="0 0 1780 1240" xmlns="http://www.w3.org/2000/svg" font-family="'Noto Sans Mono CJK SC', 'JetBrains Mono', 'WenQuanYi Zen Hei Mono', monospace">
|
|
<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 x="0" y="0" width="1800" height="1250" fill="#020617"/>
|
|
<rect width="1780" height="1240" fill="url(#grid)"/>
|
|
<rect x="160" y="240" width="320" height="360" rx="10" fill="rgba(15, 23, 42, 0.3)" stroke="#22d3ee" stroke-width="1.5" stroke-dasharray="5,3"/>
|
|
<rect x="175" y="232" width="34" height="16" fill="#0f172a"/>
|
|
<text x="192" y="243" fill="#22d3ee" font-size="9" font-weight="500" text-anchor="middle">前端层</text>
|
|
<rect x="370" y="570" width="1060" height="160" rx="10" fill="rgba(15, 23, 42, 0.3)" stroke="#34d399" stroke-width="1.5" stroke-dasharray="5,3"/>
|
|
<rect x="385" y="562" width="74" height="16" fill="#0f172a"/>
|
|
<text x="422" y="573" fill="#34d399" font-size="9" font-weight="500" text-anchor="middle">后端 API 层</text>
|
|
<rect x="1320" y="240" width="360" height="360" rx="10" fill="rgba(15, 23, 42, 0.3)" stroke="#fbbf24" stroke-width="1.5" stroke-dasharray="5,3"/>
|
|
<rect x="1335" y="232" width="50" height="16" fill="#0f172a"/>
|
|
<text x="1360" y="243" fill="#fbbf24" font-size="9" font-weight="500" text-anchor="middle">数据采集层</text>
|
|
<rect x="680" y="840" width="600" height="160" rx="10" fill="rgba(15, 23, 42, 0.3)" stroke="#a78bfa" stroke-width="1.5" stroke-dasharray="5,3"/>
|
|
<rect x="695" y="832" width="50" height="16" fill="#0f172a"/>
|
|
<text x="720" y="843" fill="#a78bfa" font-size="9" font-weight="500" text-anchor="middle">数据存储层</text>
|
|
<rect x="490" y="960" width="600" height="130" rx="10" fill="rgba(15, 23, 42, 0.3)" stroke="#fb7185" stroke-width="1.5" stroke-dasharray="5,3"/>
|
|
<rect x="505" y="952" width="58" height="16" fill="#0f172a"/>
|
|
<text x="534" y="963" fill="#fb7185" font-size="9" font-weight="500" text-anchor="middle">安全与工具层</text>
|
|
<path d="M 832.0 100.0 A 17.5 17.5 0 0 1 856.0 85.0 A 21.0 21.0 0 0 1 904.0 82.5 A 17.5 17.5 0 0 1 928.0 97.5 A 14.0 14.0 0 0 1 920.0 107.5 L 840.0 107.5 A 14.0 14.0 0 0 1 832.0 100.0 Z" fill="rgba(120, 53, 15, 0.3)" stroke="#fbbf24" stroke-width="1.5"/>
|
|
<text x="880" y="99" fill="#e2e8f0" font-size="11" font-weight="600" text-anchor="middle">用户浏览器</text>
|
|
<rect x="798" y="168" width="164" height="54" rx="8" fill="none" stroke="#fbbf24" stroke-width="1.5" opacity="0.6"/>
|
|
<rect x="800" y="170" width="160" height="50" rx="6" fill="rgba(120, 53, 15, 0.3)" stroke="#fbbf24" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="880" y="199" fill="#e2e8f0" font-size="11" font-weight="600" text-anchor="middle">Nginx 反向代理</text>
|
|
<rect x="280" y="290" width="160" height="50" rx="6" fill="#0f172a" stroke="#22d3ee" stroke-width="1.5" opacity="1.0"/>
|
|
<rect x="280" y="290" width="160" height="50" rx="6" fill="rgba(8, 51, 68, 0.4)" stroke="#22d3ee" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="360" y="308" fill="#e2e8f0" font-size="11" font-weight="600" text-anchor="middle">React + Vite</text>
|
|
<rect x="280" y="390" width="160" height="50" rx="6" fill="#0f172a" stroke="#22d3ee" stroke-width="1.5" opacity="1.0"/>
|
|
<rect x="280" y="390" width="160" height="50" rx="6" fill="rgba(8, 51, 68, 0.4)" stroke="#22d3ee" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="360" y="408" fill="#e2e8f0" font-size="11" font-weight="600" text-anchor="middle">Tailwind CSS</text>
|
|
<polygon points="815,290 945,290 960,315 945,340 815,340 800,315" fill="rgba(6, 78, 59, 0.4)" stroke="#34d399" stroke-width="1.5"/>
|
|
<text x="880" y="319" fill="#e2e8f0" font-size="11" font-weight="600" text-anchor="middle">FastAPI</text>
|
|
<rect x="800" y="390" width="160" height="50" rx="6" fill="#0f172a" stroke="#34d399" stroke-width="1.5" opacity="1.0"/>
|
|
<rect x="800" y="390" width="160" height="50" rx="6" fill="rgba(6, 78, 59, 0.4)" stroke="#34d399" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="880" y="408" fill="#e2e8f0" font-size="11" font-weight="600" text-anchor="middle">Uvicorn ASGI</text>
|
|
<rect x="1360" y="290" width="160" height="50" rx="6" fill="#0f172a" stroke="#34d399" stroke-width="1.5" opacity="1.0"/>
|
|
<rect x="1360" y="290" width="160" height="50" rx="6" fill="rgba(6, 78, 59, 0.4)" stroke="#34d399" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="1440" y="308" fill="#e2e8f0" font-size="11" font-weight="600" text-anchor="middle">Playwright</text>
|
|
<rect x="1360" y="390" width="160" height="50" rx="6" fill="#0f172a" stroke="#34d399" stroke-width="1.5" opacity="1.0"/>
|
|
<rect x="1360" y="390" width="160" height="50" rx="6" fill="rgba(6, 78, 59, 0.4)" stroke="#34d399" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="1440" y="408" fill="#e2e8f0" font-size="11" font-weight="600" text-anchor="middle">BeautifulSoup4</text>
|
|
<rect x="280" y="500" width="180" height="60" rx="6" fill="#0f172a" stroke="#22d3ee" stroke-width="1.5" opacity="1.0"/>
|
|
<rect x="280" y="500" width="180" height="60" rx="6" fill="rgba(8, 51, 68, 0.4)" stroke="#22d3ee" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="370" y="518" fill="#e2e8f0" font-size="11" font-weight="600" text-anchor="middle">前端页面
|
|
Home / Post / Dashboard / Login</text>
|
|
<rect x="400" y="630" width="140" height="60" rx="6" fill="#0f172a" stroke="#fb7185" stroke-width="1.5" opacity="1.0"/>
|
|
<rect x="400" y="630" width="140" height="60" rx="6" fill="rgba(136, 19, 55, 0.4)" stroke="#fb7185" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="470" y="648" fill="#e2e8f0" font-size="11" font-weight="600" text-anchor="middle">Auth API
|
|
(JWT认证)</text>
|
|
<rect x="570" y="630" width="140" height="60" rx="6" fill="#0f172a" stroke="#34d399" stroke-width="1.5" opacity="1.0"/>
|
|
<rect x="570" y="630" width="140" height="60" rx="6" fill="rgba(6, 78, 59, 0.4)" stroke="#34d399" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="640" y="648" fill="#e2e8f0" font-size="11" font-weight="600" text-anchor="middle">Posts API
|
|
(文章CRUD)</text>
|
|
<rect x="740" y="630" width="140" height="60" rx="6" fill="#0f172a" stroke="#34d399" stroke-width="1.5" opacity="1.0"/>
|
|
<rect x="740" y="630" width="140" height="60" rx="6" fill="rgba(6, 78, 59, 0.4)" stroke="#34d399" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="810" y="648" fill="#e2e8f0" font-size="11" font-weight="600" text-anchor="middle">Categories API
|
|
(分类管理)</text>
|
|
<rect x="910" y="630" width="140" height="60" rx="6" fill="#0f172a" stroke="#34d399" stroke-width="1.5" opacity="1.0"/>
|
|
<rect x="910" y="630" width="140" height="60" rx="6" fill="rgba(6, 78, 59, 0.4)" stroke="#34d399" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="980" y="648" fill="#e2e8f0" font-size="11" font-weight="600" text-anchor="middle">Tags API
|
|
(标签管理)</text>
|
|
<rect x="1080" y="630" width="150" height="60" rx="6" fill="#0f172a" stroke="#34d399" stroke-width="1.5" opacity="1.0"/>
|
|
<rect x="1080" y="630" width="150" height="60" rx="6" fill="rgba(6, 78, 59, 0.4)" stroke="#34d399" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="1155" y="648" fill="#e2e8f0" font-size="11" font-weight="600" text-anchor="middle">Images API
|
|
(图片上传/缩略图)</text>
|
|
<rect x="1260" y="630" width="140" height="60" rx="6" fill="#0f172a" stroke="#34d399" stroke-width="1.5" opacity="1.0"/>
|
|
<rect x="1260" y="630" width="140" height="60" rx="6" fill="rgba(6, 78, 59, 0.4)" stroke="#34d399" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="1330" y="648" fill="#e2e8f0" font-size="11" font-weight="600" text-anchor="middle">Settings API
|
|
(博客设置)</text>
|
|
<rect x="1360" y="500" width="160" height="60" rx="6" fill="#0f172a" stroke="#34d399" stroke-width="1.5" opacity="1.0"/>
|
|
<rect x="1360" y="500" width="160" height="60" rx="6" fill="rgba(6, 78, 59, 0.4)" stroke="#34d399" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="1440" y="518" fill="#e2e8f0" font-size="11" font-weight="600" text-anchor="middle">Crawl API
|
|
(网页采集)</text>
|
|
<rect x="1530" y="390" width="130" height="50" rx="6" fill="#0f172a" stroke="#fb7185" stroke-width="1.5" opacity="1.0"/>
|
|
<rect x="1530" y="390" width="130" height="50" rx="6" fill="rgba(136, 19, 55, 0.4)" stroke="#fb7185" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="1595" y="408" fill="#e2e8f0" font-size="11" font-weight="600" text-anchor="middle">Playwright
|
|
Stealth</text>
|
|
<rect x="800" y="770" width="160" height="50" rx="6" fill="#0f172a" stroke="#34d399" stroke-width="1.5" opacity="1.0"/>
|
|
<rect x="800" y="770" width="160" height="50" rx="6" fill="rgba(6, 78, 59, 0.4)" stroke="#34d399" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="880" y="788" fill="#e2e8f0" font-size="11" font-weight="600" text-anchor="middle">SQLAlchemy ORM</text>
|
|
<rect x="280" y="770" width="160" height="50" rx="6" fill="#0f172a" stroke="#94a3b8" stroke-width="1.5" opacity="1.0"/>
|
|
<rect x="280" y="770" width="160" height="50" rx="6" fill="rgba(30, 41, 59, 0.5)" stroke="#94a3b8" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="360" y="788" fill="#e2e8f0" font-size="11" font-weight="600" text-anchor="middle">Pydantic
|
|
数据校验</text>
|
|
<rect x="1080" y="770" width="150" height="50" rx="6" fill="#0f172a" stroke="#34d399" stroke-width="1.5" opacity="1.0"/>
|
|
<rect x="1080" y="770" width="150" height="50" rx="6" fill="rgba(6, 78, 59, 0.4)" stroke="#34d399" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="1155" y="788" fill="#e2e8f0" font-size="11" font-weight="600" text-anchor="middle">Pillow
|
|
缩略图生成</text>
|
|
<path d="M 800 900 L 800 940 A 80 10 0 0 0 960 940 L 960 900 A 80 10 0 0 0 800 900 Z" fill="rgba(76, 29, 149, 0.4)" stroke="#a78bfa" stroke-width="1.5"/>
|
|
<ellipse cx="880" cy="900" rx="80" ry="10" fill="rgba(76, 29, 149, 0.4)" stroke="#a78bfa" stroke-width="1.5"/>
|
|
<text x="880" y="924" fill="#e2e8f0" font-size="11" font-weight="600" text-anchor="middle">SQLite
|
|
blog.db</text>
|
|
<path d="M 1110.0 926.0 A 21.0 21.0 0 0 1 1132.5 908.0 A 25.2 25.2 0 0 1 1177.5 905.0 A 21.0 21.0 0 0 1 1200.0 923.0 A 16.8 16.8 0 0 1 1192.5 935.0 L 1117.5 935.0 A 16.8 16.8 0 0 1 1110.0 926.0 Z" fill="rgba(120, 53, 15, 0.3)" stroke="#fbbf24" stroke-width="1.5"/>
|
|
<text x="1155" y="924" fill="#e2e8f0" font-size="11" font-weight="600" text-anchor="middle">文件存储
|
|
uploads/ thumbnails/</text>
|
|
<rect x="570" y="1010" width="140" height="50" rx="6" fill="#0f172a" stroke="#fb7185" stroke-width="1.5" opacity="1.0"/>
|
|
<rect x="570" y="1010" width="140" height="50" rx="6" fill="rgba(136, 19, 55, 0.4)" stroke="#fb7185" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="640" y="1028" fill="#e2e8f0" font-size="11" font-weight="600" text-anchor="middle">python-jose
|
|
JWT令牌</text>
|
|
<rect x="740" y="1010" width="140" height="50" rx="6" fill="#0f172a" stroke="#fb7185" stroke-width="1.5" opacity="1.0"/>
|
|
<rect x="740" y="1010" width="140" height="50" rx="6" fill="rgba(136, 19, 55, 0.4)" stroke="#fb7185" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="810" y="1028" fill="#e2e8f0" font-size="11" font-weight="600" text-anchor="middle">passlib
|
|
密码哈希</text>
|
|
<rect x="910" y="1010" width="140" height="50" rx="6" fill="#0f172a" stroke="#94a3b8" stroke-width="1.5" opacity="1.0"/>
|
|
<rect x="910" y="1010" width="140" height="50" rx="6" fill="rgba(30, 41, 59, 0.5)" stroke="#94a3b8" stroke-width="1.5" opacity="1.0"/>
|
|
<text x="980" y="1028" fill="#e2e8f0" font-size="11" font-weight="600" text-anchor="middle">python-multipart
|
|
表单解析</text>
|
|
<path d="M 1556.0 200.0 A 17.5 17.5 0 0 1 1575.5 185.0 A 21.0 21.0 0 0 1 1614.5 182.5 A 17.5 17.5 0 0 1 1634.0 197.5 A 14.0 14.0 0 0 1 1627.5 207.5 L 1562.5 207.5 A 14.0 14.0 0 0 1 1556.0 200.0 Z" fill="rgba(120, 53, 15, 0.3)" stroke="#fbbf24" stroke-width="1.5"/>
|
|
<text x="1595" y="199" fill="#e2e8f0" font-size="11" font-weight="600" text-anchor="middle">外部网站
|
|
(SPA/静态)</text>
|
|
<line x1="880" y1="120" x2="880" y2="170" stroke="#64748b" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<rect x="845" y="137" width="70" height="14" fill="#0f172a" rx="2"/>
|
|
<text x="880" y="148" fill="#64748b" font-size="8" font-weight="normal" text-anchor="middle">HTTP/HTTPS</text>
|
|
<line x1="880" y1="220" x2="360" y2="290" stroke="#64748b" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<line x1="880" y1="220" x2="880" y2="290" stroke="#64748b" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<rect x="863" y="247" width="35" height="14" fill="#0f172a" rx="2"/>
|
|
<text x="880" y="258" fill="#64748b" font-size="8" font-weight="normal" text-anchor="middle">API请求</text>
|
|
<line x1="360" y1="340" x2="360" y2="390" stroke="#64748b" stroke-width="1.5" stroke-dasharray="5,3" marker-end="url(#arrowhead)"/>
|
|
<line x1="360" y1="440" x2="370" y2="500" stroke="#64748b" stroke-width="1.5" stroke-dasharray="5,3" marker-end="url(#arrowhead)"/>
|
|
<line x1="370" y1="500" x2="880" y2="220" stroke="#64748b" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<rect x="597" y="352" width="56" height="14" fill="#0f172a" rx="2"/>
|
|
<text x="625" y="363" fill="#64748b" font-size="8" font-weight="normal" text-anchor="middle">REST API</text>
|
|
<line x1="880" y1="340" x2="880" y2="390" stroke="#64748b" stroke-width="1.5" stroke-dasharray="5,3" marker-end="url(#arrowhead)"/>
|
|
<rect x="873" y="357" width="14" height="14" fill="#0f172a" rx="2"/>
|
|
<text x="880" y="368" fill="#64748b" font-size="8" font-weight="normal" text-anchor="middle">运行</text>
|
|
<line x1="880" y1="440" x2="470" y2="630" stroke="#64748b" stroke-width="1.5" stroke-dasharray="5,3" marker-end="url(#arrowhead)"/>
|
|
<line x1="880" y1="440" x2="640" y2="630" stroke="#64748b" stroke-width="1.5" stroke-dasharray="5,3" marker-end="url(#arrowhead)"/>
|
|
<line x1="880" y1="440" x2="810" y2="630" stroke="#64748b" stroke-width="1.5" stroke-dasharray="5,3" marker-end="url(#arrowhead)"/>
|
|
<line x1="880" y1="440" x2="980" y2="630" stroke="#64748b" stroke-width="1.5" stroke-dasharray="5,3" marker-end="url(#arrowhead)"/>
|
|
<line x1="880" y1="440" x2="1155" y2="630" stroke="#64748b" stroke-width="1.5" stroke-dasharray="5,3" marker-end="url(#arrowhead)"/>
|
|
<line x1="880" y1="440" x2="1330" y2="630" stroke="#64748b" stroke-width="1.5" stroke-dasharray="5,3" marker-end="url(#arrowhead)"/>
|
|
<line x1="880" y1="440" x2="1440" y2="500" stroke="#64748b" stroke-width="1.5" stroke-dasharray="5,3" marker-end="url(#arrowhead)"/>
|
|
<line x1="1440" y1="500" x2="1440" y2="340" stroke="#64748b" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<rect x="1423" y="412" width="35" height="14" fill="#0f172a" rx="2"/>
|
|
<text x="1440" y="423" fill="#64748b" font-size="8" font-weight="normal" text-anchor="middle">SPA采集</text>
|
|
<line x1="1440" y1="500" x2="1440" y2="440" stroke="#64748b" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<rect x="1419" y="462" width="42" height="14" fill="#0f172a" rx="2"/>
|
|
<text x="1440" y="473" fill="#64748b" font-size="8" font-weight="normal" text-anchor="middle">HTML解析</text>
|
|
<line x1="1440" y1="500" x2="1595" y2="440" stroke="#64748b" stroke-width="1.5" stroke-dasharray="5,3" marker-end="url(#arrowhead)"/>
|
|
<rect x="1507" y="462" width="21" height="14" fill="#0f172a" rx="2"/>
|
|
<text x="1517" y="473" fill="#64748b" font-size="8" font-weight="normal" text-anchor="middle">反检测</text>
|
|
<line x1="1440" y1="290" x2="1595" y2="220" stroke="#64748b" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<rect x="1500" y="247" width="35" height="14" fill="#0f172a" rx="2"/>
|
|
<text x="1517" y="258" fill="#64748b" font-size="8" font-weight="normal" text-anchor="middle">渲染/抓取</text>
|
|
<line x1="470" y1="690" x2="880" y2="770" stroke="#64748b" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<line x1="640" y1="690" x2="880" y2="770" stroke="#64748b" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<line x1="810" y1="690" x2="880" y2="770" stroke="#64748b" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<line x1="980" y1="690" x2="880" y2="770" stroke="#64748b" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<line x1="1155" y1="690" x2="880" y2="770" stroke="#64748b" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<line x1="1330" y1="690" x2="880" y2="770" stroke="#64748b" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<line x1="1440" y1="560" x2="880" y2="770" stroke="#64748b" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<rect x="1146" y="657" width="28" height="14" fill="#0f172a" rx="2"/>
|
|
<text x="1160" y="668" fill="#64748b" font-size="8" font-weight="normal" text-anchor="middle">写入文章</text>
|
|
<line x1="880" y1="820" x2="880" y2="890" stroke="#64748b" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<rect x="870" y="847" width="21" height="14" fill="#0f172a" rx="2"/>
|
|
<text x="880" y="858" fill="#64748b" font-size="8" font-weight="normal" text-anchor="middle">SQL</text>
|
|
<line x1="1155" y1="690" x2="1155" y2="770" stroke="#64748b" stroke-width="1.5" stroke-dasharray="5,3" marker-end="url(#arrowhead)"/>
|
|
<rect x="1148" y="722" width="14" height="14" fill="#0f172a" rx="2"/>
|
|
<text x="1155" y="733" fill="#64748b" font-size="8" font-weight="normal" text-anchor="middle">缩略</text>
|
|
<line x1="1155" y1="820" x2="1155" y2="890" stroke="#64748b" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<rect x="1148" y="847" width="14" height="14" fill="#0f172a" rx="2"/>
|
|
<text x="1155" y="858" fill="#64748b" font-size="8" font-weight="normal" text-anchor="middle">保存</text>
|
|
<line x1="470" y1="690" x2="640" y2="1010" stroke="#64748b" stroke-width="1.5" stroke-dasharray="5,3" marker-end="url(#arrowhead)"/>
|
|
<rect x="538" y="842" width="35" height="14" fill="#0f172a" rx="2"/>
|
|
<text x="555" y="853" fill="#64748b" font-size="8" font-weight="normal" text-anchor="middle">签发/验证</text>
|
|
<line x1="470" y1="690" x2="810" y2="1010" stroke="#64748b" stroke-width="1.5" stroke-dasharray="5,3" marker-end="url(#arrowhead)"/>
|
|
<rect x="619" y="842" width="42" height="14" fill="#0f172a" rx="2"/>
|
|
<text x="640" y="853" fill="#64748b" font-size="8" font-weight="normal" text-anchor="middle">bcrypt</text>
|
|
<line x1="1155" y1="690" x2="980" y2="1010" stroke="#64748b" stroke-width="1.5" stroke-dasharray="5,3" marker-end="url(#arrowhead)"/>
|
|
<rect x="1060" y="842" width="14" height="14" fill="#0f172a" rx="2"/>
|
|
<text x="1067" y="853" fill="#64748b" font-size="8" font-weight="normal" text-anchor="middle">上传</text>
|
|
<line x1="360" y1="770" x2="880" y2="340" stroke="#64748b" stroke-width="1.5" stroke-dasharray="5,3" marker-end="url(#arrowhead)"/>
|
|
<rect x="564" y="547" width="112" height="14" fill="#0f172a" rx="2"/>
|
|
<text x="620" y="558" fill="#64748b" font-size="8" font-weight="normal" text-anchor="middle">Request/Response</text>
|
|
<rect x="30" y="1170" 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="1190" fill="#64748b" font-size="10" font-weight="normal" text-anchor="start">组件类型:</text>
|
|
<rect x="120" y="1178" 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="1190" fill="#94a3b8" font-size="9" font-weight="normal" text-anchor="start">前端</text>
|
|
<rect x="195" y="1178" 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="1190" fill="#94a3b8" font-size="9" font-weight="normal" text-anchor="start">后端</text>
|
|
<rect x="270" y="1178" 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="1190" fill="#94a3b8" font-size="9" font-weight="normal" text-anchor="start">数据库</text>
|
|
<rect x="345" y="1178" 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="1190" fill="#94a3b8" font-size="9" font-weight="normal" text-anchor="start">外部API</text>
|
|
<rect x="420" y="1178" 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="1190" fill="#94a3b8" font-size="9" font-weight="normal" text-anchor="start">认证</text>
|
|
<rect x="495" y="1178" 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="1190" fill="#94a3b8" font-size="9" font-weight="normal" text-anchor="start">通用</text>
|
|
<text x="45" y="1215" fill="#64748b" font-size="10" font-weight="normal" text-anchor="start">连接类型:</text>
|
|
<line x1="120" y1="1210" x2="140" y2="1210" stroke="#64748b" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<text x="148" y="1214" fill="#94a3b8" font-size="9" font-weight="normal" text-anchor="start">数据流</text>
|
|
<line x1="195" y1="1210" x2="215" y2="1210" stroke="#fb7185" stroke-width="1.5" marker-end="url(#arrowhead-rose)"/>
|
|
<text x="223" y="1214" fill="#94a3b8" font-size="9" font-weight="normal" text-anchor="start">认证流</text>
|
|
<line x1="270" y1="1210" x2="290" y2="1210" stroke="#fbbf24" stroke-width="1.5" marker-end="url(#arrowhead-amber)"/>
|
|
<text x="298" y="1214" fill="#94a3b8" font-size="9" font-weight="normal" text-anchor="start">配置</text>
|
|
</svg>
|
|
</div>
|
|
<div class="info">生成时间: 2026-04-26 | 使用 hand-drawn-diagram 技能</div>
|
|
</body>
|
|
</html>
|