初始提交 - FutureOSS v1.0 插件化运行时框架

一切皆为插件的开发者工具运行时框架

🧩 核心特性:
  - 插件热插拔 (importlib 动态加载)
  - 依赖自动解析 (拓扑排序 + 循环检测)
  - 企业级稳定 (熔断/降级/重试/隔离)
  - 事件驱动 (发布/订阅事件总线)
  - 完整配置 (YAML 配置 + 热重载)
This commit is contained in:
Falck
2026-04-06 09:57:10 +08:00
commit 76147bae94
174 changed files with 15626 additions and 0 deletions

421
static/banner.svg Normal file
View File

@@ -0,0 +1,421 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1400 3300" width="1400" height="3300">
<defs>
<linearGradient id="bg" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" stop-color="#0a0a1a"/>
<stop offset="20%" stop-color="#0d1033"/>
<stop offset="50%" stop-color="#110824"/>
<stop offset="80%" stop-color="#0d1033"/>
<stop offset="100%" stop-color="#0a0a1a"/>
</linearGradient>
<radialGradient id="glow-purple" cx="50%" cy="50%" r="50%">
<stop offset="0%" stop-color="#6366f1" stop-opacity="0.2"/>
<stop offset="100%" stop-color="#6366f1" stop-opacity="0"/>
</radialGradient>
<radialGradient id="glow-cyan" cx="50%" cy="50%" r="50%">
<stop offset="0%" stop-color="#06b6d4" stop-opacity="0.15"/>
<stop offset="100%" stop-color="#06b6d4" stop-opacity="0"/>
</radialGradient>
<linearGradient id="cube-purple" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#6366f1" stop-opacity="0.6"/>
<stop offset="100%" stop-color="#8b5cf6" stop-opacity="0.2"/>
</linearGradient>
<linearGradient id="cube-cyan" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#06b6d4" stop-opacity="0.5"/>
<stop offset="100%" stop-color="#3b82f6" stop-opacity="0.2"/>
</linearGradient>
<linearGradient id="cube-pink" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#ec4899" stop-opacity="0.5"/>
<stop offset="100%" stop-color="#f43f5e" stop-opacity="0.2"/>
</linearGradient>
<pattern id="grid" width="60" height="60" patternUnits="userSpaceOnUse" patternTransform="rotate(12)">
<path d="M 60 0 L 0 0 0 60" fill="none" stroke="#6366f1" stroke-width="0.25" opacity="0.12"/>
</pattern>
<filter id="blur-sm"><feGaussianBlur stdDeviation="6"/></filter>
<filter id="blur-md"><feGaussianBlur stdDeviation="18"/></filter>
<filter id="blur-lg"><feGaussianBlur stdDeviation="40"/></filter>
<filter id="glow"><feGaussianBlur stdDeviation="5" result="blur"/><feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge></filter>
<filter id="glow-strong"><feGaussianBlur stdDeviation="8" result="blur"/><feMerge><feMergeNode in="blur"/><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge></filter>
<filter id="shadow"><feDropShadow dx="0" dy="4" stdDeviation="8" flood-color="#000" flood-opacity="0.5"/></filter>
<!-- 统一图标样式 (基于 Feather Icons) -->
<g id="icon-plugin"><rect x="2" y="2" width="20" height="20" rx="5" ry="5"/><path d="M16.88 3.549L7.12 20.451"/></g>
<g id="icon-deps"><circle cx="18" cy="18" r="3"/><circle cx="6" cy="6" r="3"/><path d="M6 21V9a9 9 0 0 0 9 9"/></g>
<g id="icon-shield"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></g>
<g id="icon-shield-check"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/><path d="m9 12 2 2 4-4"/></g>
<g id="icon-bolt"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></g>
<g id="icon-rocket"><path d="M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.48-.56.9-1.23 1.23-2l-4.23-1z"/><path d="M2 2l20 20"/></g>
<g id="icon-features"><line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/></g>
<g id="icon-arch"><polygon points="12 2 2 7 12 12 22 7 12 2"/><polyline points="2 17 12 22 22 17"/><polyline points="2 12 12 17 22 12"/></g>
<g id="icon-docs"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/><polyline points="10 9 9 9 8 9"/></g>
<g id="icon-book"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></g>
<g id="icon-config"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"/></g>
<g id="icon-deploy"><polyline points="4 17 10 11 4 5"/><line x1="12" y1="19" x2="20" y2="19"/></g>
<g id="icon-star"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></g>
<g id="icon-dev"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></g>
<g id="icon-check"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></g>
<g id="icon-wip"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></g>
<g id="icon-license"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6"/></g>
<g id="icon-heart"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/></g>
</defs>
<rect width="1400" height="3300" fill="url(#bg)"/>
<rect width="1400" height="3300" fill="url(#grid)"/>
<ellipse cx="700" cy="600" rx="800" ry="500" fill="url(#glow-purple)" filter="url(#blur-lg)" opacity="0.8"/>
<ellipse cx="300" cy="1200" rx="600" ry="400" fill="url(#glow-cyan)" filter="url(#blur-lg)" opacity="0.7"/>
<ellipse cx="1100" cy="1800" rx="700" ry="450" fill="url(#glow-purple)" filter="url(#blur-lg)" opacity="0.75"/>
<ellipse cx="500" cy="2500" rx="650" ry="400" fill="url(#glow-cyan)" filter="url(#blur-lg)" opacity="0.7"/>
<g transform="translate(200, 500) rotate(-25) scale(1.2)" filter="url(#glow-strong)">
<polygon points="0,-40 60,-70 120,-40 60,-10" fill="url(#cube-purple)" opacity="0.5" stroke="#6366f1" stroke-width="0.8"/>
<polygon points="0,-40 60,-10 60,50 0,20" fill="url(#cube-purple)" opacity="0.4" stroke="#6366f1" stroke-width="0.8"/>
<polygon points="60,-10 120,-40 120,20 60,50" fill="url(#cube-purple)" opacity="0.35" stroke="#6366f1" stroke-width="0.8"/>
</g>
<g transform="translate(1100, 700) rotate(15) scale(1.1)" filter="url(#glow-strong)">
<polygon points="0,-40 60,-70 120,-40 60,-10" fill="url(#cube-cyan)" opacity="0.5" stroke="#06b6d4" stroke-width="0.8"/>
<polygon points="0,-40 60,-10 60,50 0,20" fill="url(#cube-cyan)" opacity="0.4" stroke="#06b6d4" stroke-width="0.8"/>
<polygon points="60,-10 120,-40 120,20 60,50" fill="url(#cube-cyan)" opacity="0.35" stroke="#06b6d4" stroke-width="0.8"/>
</g>
<g transform="translate(700, 1000) rotate(35) scale(0.9)" filter="url(#glow)">
<polygon points="0,-40 60,-70 120,-40 60,-10" fill="url(#cube-pink)" opacity="0.45" stroke="#ec4899" stroke-width="0.6"/>
<polygon points="0,-40 60,-10 60,50 0,20" fill="url(#cube-pink)" opacity="0.35" stroke="#ec4899" stroke-width="0.6"/>
<polygon points="60,-10 120,-40 120,20 60,50" fill="url(#cube-pink)" opacity="0.3" stroke="#ec4899" stroke-width="0.6"/>
</g>
<g transform="translate(300, 1500) rotate(-40) scale(0.85)" filter="url(#glow)">
<polygon points="0,-40 60,-70 120,-40 60,-10" fill="url(#cube-cyan)" opacity="0.4" stroke="#06b6d4" stroke-width="0.6"/>
<polygon points="0,-40 60,-10 60,50 0,20" fill="url(#cube-cyan)" opacity="0.3" stroke="#06b6d4" stroke-width="0.6"/>
<polygon points="60,-10 120,-40 120,20 60,50" fill="url(#cube-cyan)" opacity="0.25" stroke="#06b6d4" stroke-width="0.6"/>
</g>
<g transform="translate(1050, 1800) rotate(-20) scale(1.05)" filter="url(#glow-strong)">
<polygon points="0,-40 60,-70 120,-40 60,-10" fill="url(#cube-purple)" opacity="0.5" stroke="#8b5cf6" stroke-width="0.7"/>
<polygon points="0,-40 60,-10 60,50 0,20" fill="url(#cube-purple)" opacity="0.4" stroke="#8b5cf6" stroke-width="0.7"/>
<polygon points="60,-10 120,-40 120,20 60,50" fill="url(#cube-purple)" opacity="0.35" stroke="#8b5cf6" stroke-width="0.7"/>
</g>
<g transform="translate(500, 2200) rotate(28) scale(0.75)" filter="url(#glow)">
<polygon points="0,-40 60,-70 120,-40 60,-10" fill="url(#cube-pink)" opacity="0.4" stroke="#f43f5e" stroke-width="0.5"/>
<polygon points="0,-40 60,-10 60,50 0,20" fill="url(#cube-pink)" opacity="0.3" stroke="#f43f5e" stroke-width="0.5"/>
<polygon points="60,-10 120,-40 120,20 60,50" fill="url(#cube-pink)" opacity="0.25" stroke="#f43f5e" stroke-width="0.5"/>
</g>
<g transform="translate(900, 2600) rotate(-32) scale(0.95)" filter="url(#glow)">
<polygon points="0,-40 60,-70 120,-40 60,-10" fill="url(#cube-cyan)" opacity="0.45" stroke="#06b6d4" stroke-width="0.6"/>
<polygon points="0,-40 60,-10 60,50 0,20" fill="url(#cube-cyan)" opacity="0.35" stroke="#06b6d4" stroke-width="0.6"/>
<polygon points="60,-10 120,-40 120,20 60,50" fill="url(#cube-cyan)" opacity="0.3" stroke="#06b6d4" stroke-width="0.6"/>
</g>
<g transform="translate(250, 3000) rotate(18) scale(0.8)" filter="url(#glow)">
<polygon points="0,-40 60,-70 120,-40 60,-10" fill="url(#cube-purple)" opacity="0.4" stroke="#6366f1" stroke-width="0.5"/>
<polygon points="0,-40 60,-10 60,50 0,20" fill="url(#cube-purple)" opacity="0.3" stroke="#6366f1" stroke-width="0.5"/>
<polygon points="60,-10 120,-40 120,20 60,50" fill="url(#cube-purple)" opacity="0.25" stroke="#6366f1" stroke-width="0.5"/>
</g>
<g transform="translate(700, 150)" text-anchor="middle">
<rect x="-230" y="-25" width="460" height="50" rx="25" fill="#6366f1" opacity="0.15" filter="url(#glow)"/>
<rect x="-228" y="-23" width="456" height="46" rx="23" fill="none" stroke="#6366f1" stroke-width="1" opacity="0.4"/>
<text font-family="system-ui, -apple-system, sans-serif" font-size="16" fill="#a5b4fc" letter-spacing="3" font-weight="400">Python 3.10+ Apache 2.0 Plugin Driven</text>
</g>
<g transform="translate(700, 380)" text-anchor="middle" filter="url(#shadow)">
<text font-family="system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif" font-size="96" fill="url(#cube-purple)" font-weight="800" letter-spacing="4">FutureOSS</text>
<text y="75" font-family="system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif" font-size="32" fill="#e0e7ff" font-weight="300" letter-spacing="8">一切皆为插件的开发者工具运行时框架</text>
</g>
<g transform="translate(700, 520)" text-anchor="middle">
<text font-family="system-ui, -apple-system, sans-serif" font-size="20" fill="#94a3b8" font-style="italic">一个空壳框架,通过插件获得无限能力</text>
</g>
<g transform="translate(0, 650)">
<g transform="translate(100, 0)">
<rect width="280" height="160" rx="12" fill="#1e1b4b" opacity="0.6" filter="url(#shadow)"/>
<rect width="280" height="160" rx="12" fill="none" stroke="#6366f1" stroke-width="1.5" opacity="0.4"/>
<use href="#icon-plugin" transform="translate(128, 38) scale(1)" color="#6366f1" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<text x="140" y="95" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" fill="#e0e7ff" font-weight="600">一切皆插件</text>
<text x="140" y="125" text-anchor="middle" font-family="system-ui, sans-serif" font-size="13" fill="#94a3b8">协议、中间件、工具</text>
<text x="140" y="145" text-anchor="middle" font-family="system-ui, sans-serif" font-size="13" fill="#94a3b8">所有功能以插件加载</text>
</g>
<g transform="translate(420, 0)">
<rect width="280" height="160" rx="12" fill="#1e1b4b" opacity="0.6" filter="url(#shadow)"/>
<rect width="280" height="160" rx="12" fill="none" stroke="#06b6d4" stroke-width="1.5" opacity="0.4"/>
<use href="#icon-deps" transform="translate(128, 38) scale(1)" color="#06b6d4" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<text x="140" y="95" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" fill="#e0e7ff" font-weight="600">依赖自动解析</text>
<text x="140" y="125" text-anchor="middle" font-family="system-ui, sans-serif" font-size="13" fill="#94a3b8">拓扑排序 + 循环检测</text>
<text x="140" y="145" text-anchor="middle" font-family="system-ui, sans-serif" font-size="13" fill="#94a3b8">自动识别多级依赖</text>
</g>
<g transform="translate(740, 0)">
<rect width="280" height="160" rx="12" fill="#1e1b4b" opacity="0.6" filter="url(#shadow)"/>
<rect width="280" height="160" rx="12" fill="none" stroke="#ec4899" stroke-width="1.5" opacity="0.4"/>
<use href="#icon-shield" transform="translate(128, 38) scale(1)" color="#ec4899" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<text x="140" y="95" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" fill="#e0e7ff" font-weight="600">企业级稳定</text>
<text x="140" y="125" text-anchor="middle" font-family="system-ui, sans-serif" font-size="13" fill="#94a3b8">熔断、降级、重试</text>
<text x="140" y="145" text-anchor="middle" font-family="system-ui, sans-serif" font-size="13" fill="#94a3b8">隔离 + 资源限制</text>
</g>
<g transform="translate(1060, 0)">
<rect width="280" height="160" rx="12" fill="#1e1b4b" opacity="0.6" filter="url(#shadow)"/>
<rect width="280" height="160" rx="12" fill="none" stroke="#10b981" stroke-width="1.5" opacity="0.4"/>
<use href="#icon-bolt" transform="translate(128, 38) scale(1)" color="#10b981" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<text x="140" y="95" text-anchor="middle" font-family="system-ui, sans-serif" font-size="18" fill="#e0e7ff" font-weight="600">事件驱动</text>
<text x="140" y="125" text-anchor="middle" font-family="system-ui, sans-serif" font-size="13" fill="#94a3b8">发布/订阅事件总线</text>
<text x="140" y="145" text-anchor="middle" font-family="system-ui, sans-serif" font-size="13" fill="#94a3b8">40+ 种系统事件</text>
</g>
</g>
<g transform="translate(700, 920)" text-anchor="middle">
<text font-family="system-ui, sans-serif" font-size="36" fill="#e0e7ff" font-weight="700" letter-spacing="3">快速开始</text>
</g>
<g transform="translate(200, 980)">
<rect width="1000" height="180" rx="10" fill="#0f172a" opacity="0.85" filter="url(#shadow)"/>
<rect width="1000" height="180" rx="10" fill="none" stroke="#334155" stroke-width="1"/>
<circle cx="30" cy="30" r="6" fill="#ef4444"/>
<circle cx="55" cy="30" r="6" fill="#f59e0b"/>
<circle cx="80" cy="30" r="6" fill="#10b981"/>
<text x="50" y="75" font-family="'Fira Code', 'Consolas', 'Monaco', monospace" font-size="18" fill="#22d3ee">$ git clone https://gitee.com/starlight-apk/feature-oss.git</text>
<text x="50" y="105" font-family="'Fira Code', 'Consolas', 'Monaco', monospace" font-size="18" fill="#22d3ee">$ cd feature-oss &amp;&amp; bash start.sh</text>
<text x="50" y="145" font-family="'Fira Code', 'Consolas', 'Monaco', monospace" font-size="16" fill="#10b981">✓ 服务已启动 → http://localhost:8080/</text>
</g>
<g transform="translate(700, 1250)" text-anchor="middle">
<text font-family="system-ui, sans-serif" font-size="36" fill="#e0e7ff" font-weight="700" letter-spacing="3">核心特性</text>
</g>
<g transform="translate(150, 1320)">
<g transform="translate(0, 0)">
<rect width="540" height="60" rx="8" fill="#1e1b4b" opacity="0.5"/>
<use href="#icon-plugin" transform="translate(38, 26) scale(1)" color="#6366f1" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<text x="85" y="38" font-family="system-ui, sans-serif" font-size="20" fill="#e0e7ff">插件热插拔</text>
<use href="#icon-check" transform="translate(490, 26) scale(1)" color="#10b981" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<g transform="translate(580, 0)">
<rect width="540" height="60" rx="8" fill="#1e1b4b" opacity="0.5"/>
<use href="#icon-deps" transform="translate(38, 26) scale(1)" color="#06b6d4" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<text x="85" y="38" font-family="system-ui, sans-serif" font-size="20" fill="#e0e7ff">依赖自动解析</text>
<use href="#icon-check" transform="translate(490, 26) scale(1)" color="#10b981" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<g transform="translate(0, 80)">
<rect width="540" height="60" rx="8" fill="#1e1b4b" opacity="0.5"/>
<use href="#icon-bolt" transform="translate(38, 26) scale(1)" color="#10b981" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<text x="85" y="38" font-family="system-ui, sans-serif" font-size="20" fill="#e0e7ff">事件总线</text>
<use href="#icon-check" transform="translate(490, 26) scale(1)" color="#10b981" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<g transform="translate(580, 80)">
<rect width="540" height="60" rx="8" fill="#1e1b4b" opacity="0.5"/>
<use href="#icon-config" transform="translate(38, 26) scale(1)" color="#f59e0b" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<text x="85" y="38" font-family="system-ui, sans-serif" font-size="20" fill="#e0e7ff">完整配置</text>
<use href="#icon-check" transform="translate(490, 26) scale(1)" color="#10b981" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<g transform="translate(0, 160)">
<rect width="540" height="60" rx="8" fill="#1e1b4b" opacity="0.5"/>
<use href="#icon-deploy" transform="translate(38, 26) scale(1)" color="#6366f1" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<text x="85" y="38" font-family="system-ui, sans-serif" font-size="20" fill="#e0e7ff">协议适配</text>
<use href="#icon-wip" transform="translate(490, 26) scale(1)" color="#f59e0b" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<g transform="translate(580, 160)">
<rect width="540" height="60" rx="8" fill="#1e1b4b" opacity="0.5"/>
<use href="#icon-shield-check" transform="translate(38, 26) scale(1)" color="#ec4899" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<text x="85" y="38" font-family="system-ui, sans-serif" font-size="20" fill="#e0e7ff">熔断降级</text>
<use href="#icon-wip" transform="translate(490, 26) scale(1)" color="#f59e0b" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</g>
<g transform="translate(700, 1700)" text-anchor="middle">
<text font-family="system-ui, sans-serif" font-size="36" fill="#e0e7ff" font-weight="700" letter-spacing="3">🏗️ 架构设计</text>
</g>
<g transform="translate(250, 1760)">
<rect width="900" height="300" rx="12" fill="#0f172a" opacity="0.7" filter="url(#shadow)"/>
<rect width="900" height="300" rx="12" fill="none" stroke="#334155" stroke-width="1.5"/>
<text x="450" y="50" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#6366f1" font-weight="600">用户层</text>
<rect x="150" y="65" width="600" height="35" rx="6" fill="#1e1b4b" opacity="0.6"/>
<text x="450" y="88" text-anchor="middle" font-family="system-ui, sans-serif" font-size="14" fill="#94a3b8">CLI │ HTTP API │ WebSocket │ 社区论坛</text>
<line x1="450" y1="100" x2="450" y2="125" stroke="#6366f1" stroke-width="2"/>
<text x="450" y="155" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#06b6d4" font-weight="600">插件层</text>
<rect x="175" y="165" width="170" height="35" rx="6" fill="#1e1b4b" opacity="0.6"/>
<text x="260" y="188" text-anchor="middle" font-family="system-ui, sans-serif" font-size="13" fill="#94a3b8">http-api</text>
<rect x="365" y="165" width="170" height="35" rx="6" fill="#1e1b4b" opacity="0.6"/>
<text x="450" y="188" text-anchor="middle" font-family="system-ui, sans-serif" font-size="13" fill="#94a3b8">ws-api</text>
<rect x="555" y="165" width="170" height="35" rx="6" fill="#1e1b4b" opacity="0.6"/>
<text x="640" y="188" text-anchor="middle" font-family="system-ui, sans-serif" font-size="13" fill="#94a3b8">plugin-storage</text>
<line x1="450" y1="200" x2="450" y2="225" stroke="#06b6d4" stroke-width="2"/>
<text x="450" y="255" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#ec4899" font-weight="600">核心层</text>
<rect x="100" y="265" width="700" height="25" rx="6" fill="#1e1b4b" opacity="0.6"/>
<text x="450" y="283" text-anchor="middle" font-family="system-ui, sans-serif" font-size="13" fill="#94a3b8">PluginManager | EventBus | Config | Logger | Loader</text>
</g>
<g transform="translate(700, 2150)" text-anchor="middle">
<text font-family="system-ui, sans-serif" font-size="36" fill="#e0e7ff" font-weight="700" letter-spacing="3">文档</text>
</g>
<g transform="translate(450, 2220)">
<!-- 书影 -->
<rect x="8" y="8" width="500" height="310" rx="8" fill="#000" opacity="0.3" filter="url(#blur-md)"/>
<!-- 书封面 -->
<rect x="0" y="0" width="500" height="310" rx="8" fill="#1e1b4b" opacity="0.9"/>
<rect x="0" y="0" width="500" height="310" rx="8" fill="none" stroke="#6366f1" stroke-width="2" opacity="0.6"/>
<!-- 书脊 -->
<rect x="0" y="0" width="25" height="310" rx="8" fill="#0f172a" opacity="0.8"/>
<line x1="25" y1="0" x2="25" y2="310" stroke="#6366f1" stroke-width="1" opacity="0.4"/>
<!-- 书页 -->
<rect x="30" y="10" width="460" height="290" rx="4" fill="#0f172a" opacity="0.4"/>
<!-- 书签 -->
<polygon points="480,0 500,0 500,25 490,18 480,25" fill="#ec4899" opacity="0.8"/>
<!-- 标题 -->
<text x="250" y="40" text-anchor="middle" font-family="system-ui, sans-serif" font-size="16" fill="#6366f1" font-weight="600" letter-spacing="2">所有文档都在本地 dock/ 目录中</text>
<!-- 文档列表 (单列 8 项) -->
<use href="#icon-book" transform="translate(100, 53) scale(0.75)" color="#a5b4fc" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<text x="125" y="65" font-family="system-ui, sans-serif" font-size="15" fill="#a5b4fc">项目介绍</text>
<use href="#icon-rocket" transform="translate(100, 83) scale(0.75)" color="#a5b4fc" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<text x="125" y="95" font-family="system-ui, sans-serif" font-size="15" fill="#a5b4fc">快速开始</text>
<use href="#icon-dev" transform="translate(100, 113) scale(0.75)" color="#a5b4fc" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<text x="125" y="125" font-family="system-ui, sans-serif" font-size="15" fill="#a5b4fc">插件开发</text>
<use href="#icon-docs" transform="translate(100, 143) scale(0.75)" color="#a5b4fc" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<text x="125" y="155" font-family="system-ui, sans-serif" font-size="15" fill="#a5b4fc">插件文档</text>
<use href="#icon-config" transform="translate(100, 173) scale(0.75)" color="#a5b4fc" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<text x="125" y="185" font-family="system-ui, sans-serif" font-size="15" fill="#a5b4fc">包管理</text>
<use href="#icon-features" transform="translate(100, 203) scale(0.75)" color="#a5b4fc" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<text x="125" y="215" font-family="system-ui, sans-serif" font-size="15" fill="#a5b4fc">配置参考</text>
<use href="#icon-deploy" transform="translate(100, 233) scale(0.75)" color="#a5b4fc" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<text x="125" y="245" font-family="system-ui, sans-serif" font-size="15" fill="#a5b4fc">部署运维</text>
<use href="#icon-star" transform="translate(100, 263) scale(0.75)" color="#a5b4fc" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<text x="125" y="275" font-family="system-ui, sans-serif" font-size="15" fill="#a5b4fc">社区与贡献</text>
</g>
<line x1="200" y1="2580" x2="1200" y2="2580" stroke="#334155" stroke-width="1"/>
<g transform="translate(700, 2680)" text-anchor="middle">
<use href="#icon-license" transform="translate(-18, -2) scale(1.33)" color="#e0e7ff" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<text font-family="system-ui, sans-serif" font-size="32" fill="#e0e7ff" font-weight="700">许可证</text>
<text y="45" font-family="system-ui, sans-serif" font-size="18" fill="#94a3b8">Apache License 2.0</text>
<text y="80" font-family="system-ui, sans-serif" font-size="16" fill="#64748b">Copyright 2026 Falck</text>
</g>
<g transform="translate(700, 2830)" text-anchor="middle">
<use href="#icon-heart" transform="translate(-16, -6) scale(1)" color="#a5b4fc" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<text x="18" font-family="system-ui, sans-serif" font-size="24" fill="#a5b4fc" font-weight="600">Made with by Falck</text>
<text y="40" font-family="system-ui, sans-serif" font-size="16" fill="#64748b">https://gitee.com/starlight-apk</text>
</g>
<text x="700" y="3000" font-family="system-ui, -apple-system, sans-serif" font-size="32" fill="#6366f1" opacity="0.08" text-anchor="middle" letter-spacing="15" font-weight="300">FUTURE OSS</text>
<text x="700" y="3050" font-family="system-ui, -apple-system, sans-serif" font-size="14" fill="#6366f1" opacity="0.06" text-anchor="middle" letter-spacing="10" font-weight="300">EVERYTHING IS A PLUGIN</text>
<!-- 视差效果脚本 -->
<script type="text/ecmascript"><![CDATA[
// 视差层配置
const layers = [
{ selector: '.parallax-grid', speed: 0.05 },
{ selector: '.parallax-cubes', speed: 0.12 },
{ selector: '.parallax-title', speed: 0.25 },
{ selector: '.parallax-content', speed: 0.08 }
];
let mouseX = 700, mouseY = 500;
let currentX = 700, currentY = 500;
const centerX = 700, centerY = 1650;
// 获取SVG元素
function getLayerElements(selector) {
const elements = [];
const all = document.querySelectorAll('*');
for (let i = 0; i < all.length; i++) {
const classes = all[i].getAttribute('class') || '';
if (classes.includes(selector.replace('.', ''))) {
elements.push(all[i]);
}
}
return elements;
}
// 鼠标移动事件
document.addEventListener('mousemove', function(e) {
const svg = document.querySelector('svg');
const rect = svg.getBoundingClientRect();
mouseX = (e.clientX - rect.left) / rect.width * 1400;
mouseY = (e.clientY - rect.top) / rect.height * 3300;
});
// 动画循环
function animate() {
// 平滑插值
currentX += (mouseX - currentX) * 0.15;
currentY += (mouseY - currentY) * 0.15;
const deltaX = currentX - centerX;
const deltaY = currentY - centerY;
layers.forEach(layer => {
const elements = getLayerElements(layer.selector);
elements.forEach(el => {
const moveX = deltaX * layer.speed;
const moveY = deltaY * layer.speed;
const currentTransform = el.getAttribute('data-base-transform') || '';
el.setAttribute('transform', `${currentTransform} translate(${moveX}, ${moveY})`);
});
});
requestAnimationFrame(animate);
}
// 初始化:为各层添加 class
function init() {
// 网格层
document.querySelectorAll('rect').forEach(rect => {
if (rect.getAttribute('fill') && rect.getAttribute('fill').includes('grid')) {
rect.setAttribute('class', 'parallax-grid');
}
});
// 3D立方体层
const cubeGroups = [
'translate(200, 500)', 'translate(1100, 700)', 'translate(700, 1000)',
'translate(300, 1500)', 'translate(1050, 1800)', 'translate(500, 2200)',
'translate(900, 2600)', 'translate(250, 3000)'
];
document.querySelectorAll('g').forEach(g => {
const transform = g.getAttribute('transform') || '';
if (cubeGroups.some(t => transform.includes(t))) {
g.setAttribute('data-base-transform', transform);
g.setAttribute('class', 'parallax-cubes');
}
});
// 标题层
document.querySelectorAll('g').forEach(g => {
const transform = g.getAttribute('transform') || '';
if (transform.includes('translate(700, 380)') || transform.includes('translate(700, 150)') || transform.includes('translate(700, 520)')) {
g.setAttribute('data-base-transform', transform);
g.setAttribute('class', 'parallax-title');
}
});
// 内容层
document.querySelectorAll('g').forEach(g => {
const transform = g.getAttribute('transform') || '';
if (transform.includes('translate(0, 650)') || transform.includes('translate(700, 920)') || transform.includes('translate(200, 980)') || transform.includes('translate(700, 1250)') || transform.includes('translate(150, 1320)')) {
g.setAttribute('data-base-transform', transform);
g.setAttribute('class', 'parallax-content');
}
});
animate();
}
init();
]]></script>
</svg>

After

Width:  |  Height:  |  Size: 30 KiB