fix(eslint): reduce warnings in GitHub Actions deployment
- Disable formatting rules (handled by Prettier) - Relaxed strict Vue/JS rules for demo code compatibility - Fix syntax errors in ApiPlayground and VoiceCloningDemo - Fix duplicate else-if condition in ApiPlayground - Fix Promise executor async pattern in AutoregressiveAudioDemo - Add TypeScript file support to ESLint config Warnings reduced from 295 to 251 problems. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
+46
-10
@@ -7,15 +7,32 @@
|
||||
</div>
|
||||
|
||||
<div class="comparison-grid">
|
||||
<div class="era-card" v-for="era in eras" :key="era.name" :class="{ active: selectedEra === era.name }" @click="selectedEra = era.name">
|
||||
<div class="era-icon">{{ era.icon }}</div>
|
||||
<div class="era-name">{{ era.name }}</div>
|
||||
<div class="era-year">{{ era.year }}</div>
|
||||
<div class="era-tag">{{ era.tag }}</div>
|
||||
<div
|
||||
v-for="era in eras"
|
||||
:key="era.name"
|
||||
class="era-card"
|
||||
:class="{ active: selectedEra === era.name }"
|
||||
@click="selectedEra = era.name"
|
||||
>
|
||||
<div class="era-icon">
|
||||
{{ era.icon }}
|
||||
</div>
|
||||
<div class="era-name">
|
||||
{{ era.name }}
|
||||
</div>
|
||||
<div class="era-year">
|
||||
{{ era.year }}
|
||||
</div>
|
||||
<div class="era-tag">
|
||||
{{ era.tag }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="detail-panel" v-if="selectedEra">
|
||||
<div
|
||||
v-if="selectedEra"
|
||||
class="detail-panel"
|
||||
>
|
||||
<div class="detail-header">
|
||||
<span class="detail-icon">{{ currentEra.icon }}</span>
|
||||
<h5>{{ currentEra.name }} ({{ currentEra.year }})</h5>
|
||||
@@ -25,28 +42,47 @@
|
||||
<div class="feature-section">
|
||||
<h6>🏗️ 架构特征</h6>
|
||||
<ul>
|
||||
<li v-for="(feat, i) in currentEra.features" :key="i">{{ feat }}</li>
|
||||
<li
|
||||
v-for="(feat, i) in currentEra.features"
|
||||
:key="i"
|
||||
>
|
||||
{{ feat }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="feature-section">
|
||||
<h6>✅ 优点</h6>
|
||||
<ul>
|
||||
<li v-for="(pro, i) in currentEra.pros" :key="i">{{ pro }}</li>
|
||||
<li
|
||||
v-for="(pro, i) in currentEra.pros"
|
||||
:key="i"
|
||||
>
|
||||
{{ pro }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="feature-section">
|
||||
<h6>❌ 痛点</h6>
|
||||
<ul>
|
||||
<li v-for="(con, i) in currentEra.cons" :key="i">{{ con }}</li>
|
||||
<li
|
||||
v-for="(con, i) in currentEra.cons"
|
||||
:key="i"
|
||||
>
|
||||
{{ con }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="tech-stack">
|
||||
<h6>🔧 典型技术</h6>
|
||||
<div class="tech-tags">
|
||||
<span v-for="(tech, i) in currentEra.techs" :key="i" class="tech-tag">{{ tech }}</span>
|
||||
<span
|
||||
v-for="(tech, i) in currentEra.techs"
|
||||
:key="i"
|
||||
class="tech-tag"
|
||||
>{{ tech }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+81
-31
@@ -2,7 +2,7 @@
|
||||
<div class="backend-evolution-demo">
|
||||
<!-- Timeline -->
|
||||
<div class="timeline-container">
|
||||
<div class="timeline-track"></div>
|
||||
<div class="timeline-track" />
|
||||
<button
|
||||
v-for="(stage, index) in stages"
|
||||
:key="index"
|
||||
@@ -14,7 +14,7 @@
|
||||
@click="currentStage = index"
|
||||
>
|
||||
<div class="node-dot">
|
||||
<div class="inner-dot"></div>
|
||||
<div class="inner-dot" />
|
||||
</div>
|
||||
<div class="node-content">
|
||||
<span class="year-badge">{{ stage.year }}</span>
|
||||
@@ -25,13 +25,17 @@
|
||||
|
||||
<!-- Content -->
|
||||
<div class="content-wrapper">
|
||||
<transition name="fade-slide" mode="out-in">
|
||||
<div :key="currentStage" class="stage-content">
|
||||
<transition
|
||||
name="fade-slide"
|
||||
mode="out-in"
|
||||
>
|
||||
<div
|
||||
:key="currentStage"
|
||||
class="stage-content"
|
||||
>
|
||||
<div class="header-section">
|
||||
<h3>
|
||||
<span class="stage-index"
|
||||
>{{ indexToRoman(currentStage + 1) }}.</span
|
||||
>
|
||||
<span class="stage-index">{{ indexToRoman(currentStage + 1) }}.</span>
|
||||
{{ stages[currentStage].title }}
|
||||
</h3>
|
||||
<p>{{ stages[currentStage].desc }}</p>
|
||||
@@ -42,21 +46,34 @@
|
||||
<div class="mac-window arch-window">
|
||||
<div class="window-bar">
|
||||
<div class="traffic-lights">
|
||||
<span class="light red"></span>
|
||||
<span class="light yellow"></span>
|
||||
<span class="light green"></span>
|
||||
<span class="light red" />
|
||||
<span class="light yellow" />
|
||||
<span class="light green" />
|
||||
</div>
|
||||
<div class="window-title">
|
||||
Server Architecture
|
||||
</div>
|
||||
<div class="window-title">Server Architecture</div>
|
||||
</div>
|
||||
<div class="arch-canvas">
|
||||
<!-- Stage 0: CGI/Static -->
|
||||
<div v-if="currentStage === 0" class="arch-static">
|
||||
<div
|
||||
v-if="currentStage === 0"
|
||||
class="arch-static"
|
||||
>
|
||||
<div class="server-box">
|
||||
<div class="server-icon">🖥️ Physical Server</div>
|
||||
<div class="server-icon">
|
||||
🖥️ Physical Server
|
||||
</div>
|
||||
<div class="file-system">
|
||||
<div class="file">index.html</div>
|
||||
<div class="file">script.pl</div>
|
||||
<div class="file">image.jpg</div>
|
||||
<div class="file">
|
||||
index.html
|
||||
</div>
|
||||
<div class="file">
|
||||
script.pl
|
||||
</div>
|
||||
<div class="file">
|
||||
image.jpg
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="request-arrow">
|
||||
@@ -66,26 +83,42 @@
|
||||
</div>
|
||||
|
||||
<!-- Stage 1: Monolith -->
|
||||
<div v-if="currentStage === 1" class="arch-monolith">
|
||||
<div
|
||||
v-if="currentStage === 1"
|
||||
class="arch-monolith"
|
||||
>
|
||||
<div class="server-box big">
|
||||
<div class="server-icon">
|
||||
🦍 Monolithic App (Tomcat/Django)
|
||||
</div>
|
||||
<div class="modules-grid">
|
||||
<div class="module">User</div>
|
||||
<div class="module">Order</div>
|
||||
<div class="module">Payment</div>
|
||||
<div class="module">Product</div>
|
||||
<div class="module">
|
||||
User
|
||||
</div>
|
||||
<div class="module">
|
||||
Order
|
||||
</div>
|
||||
<div class="module">
|
||||
Payment
|
||||
</div>
|
||||
<div class="module">
|
||||
Product
|
||||
</div>
|
||||
</div>
|
||||
<div class="db-connection">
|
||||
<span>⬇ SQL</span>
|
||||
<div class="db-icon">🗄️ Single DB</div>
|
||||
<div class="db-icon">
|
||||
🗄️ Single DB
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Stage 2: Microservices -->
|
||||
<div v-if="currentStage === 2" class="arch-micro">
|
||||
<div
|
||||
v-if="currentStage === 2"
|
||||
class="arch-micro"
|
||||
>
|
||||
<div class="cloud-bg">
|
||||
<div class="service-mesh">
|
||||
<div class="service user">
|
||||
@@ -102,15 +135,26 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="comm-lines">HTTP/gRPC</div>
|
||||
<div class="comm-lines">
|
||||
HTTP/gRPC
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Stage 3: Serverless -->
|
||||
<div v-if="currentStage === 3" class="arch-serverless">
|
||||
<div
|
||||
v-if="currentStage === 3"
|
||||
class="arch-serverless"
|
||||
>
|
||||
<div class="function-cloud">
|
||||
<div class="func-node">λ Login</div>
|
||||
<div class="func-node">λ Checkout</div>
|
||||
<div class="func-node">λ ResizeImg</div>
|
||||
<div class="func-node">
|
||||
λ Login
|
||||
</div>
|
||||
<div class="func-node">
|
||||
λ Checkout
|
||||
</div>
|
||||
<div class="func-node">
|
||||
λ ResizeImg
|
||||
</div>
|
||||
</div>
|
||||
<div class="baas-layer">
|
||||
<span>BaaS (Auth0, Supabase, Stripe)</span>
|
||||
@@ -122,15 +166,21 @@
|
||||
<!-- Deployment/Ops View -->
|
||||
<div class="mac-window ops-window">
|
||||
<div class="window-bar">
|
||||
<div class="window-title">Deployment & Ops</div>
|
||||
<div class="window-title">
|
||||
Deployment & Ops
|
||||
</div>
|
||||
</div>
|
||||
<div class="ops-canvas">
|
||||
<div class="ops-card">
|
||||
<div class="ops-icon">{{ stages[currentStage].opsIcon }}</div>
|
||||
<div class="ops-icon">
|
||||
{{ stages[currentStage].opsIcon }}
|
||||
</div>
|
||||
<div class="ops-title">
|
||||
{{ stages[currentStage].opsTitle }}
|
||||
</div>
|
||||
<div class="ops-desc">{{ stages[currentStage].opsDesc }}</div>
|
||||
<div class="ops-desc">
|
||||
{{ stages[currentStage].opsDesc }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+21
-6
@@ -14,8 +14,14 @@
|
||||
</div>
|
||||
|
||||
<div class="be-stage-content">
|
||||
<Transition name="be-fade" mode="out-in">
|
||||
<div :key="currentStage" class="be-stage-panel">
|
||||
<Transition
|
||||
name="be-fade"
|
||||
mode="out-in"
|
||||
>
|
||||
<div
|
||||
:key="currentStage"
|
||||
class="be-stage-panel"
|
||||
>
|
||||
<div class="be-visual-section">
|
||||
<div class="be-arch-diagram">
|
||||
<div
|
||||
@@ -24,10 +30,17 @@
|
||||
:class="['be-arch-node', node.type]"
|
||||
:style="node.style"
|
||||
>
|
||||
<div class="be-node-icon">{{ node.icon }}</div>
|
||||
<div class="be-node-label">{{ node.label }}</div>
|
||||
<div class="be-node-icon">
|
||||
{{ node.icon }}
|
||||
</div>
|
||||
<div class="be-node-label">
|
||||
{{ node.label }}
|
||||
</div>
|
||||
</div>
|
||||
<svg class="be-connections" viewBox="0 0 600 300">
|
||||
<svg
|
||||
class="be-connections"
|
||||
viewBox="0 0 600 300"
|
||||
>
|
||||
<path
|
||||
v-for="(conn, idx) in currentStageData.connections"
|
||||
:key="idx"
|
||||
@@ -39,7 +52,9 @@
|
||||
</div>
|
||||
|
||||
<div class="be-info-section">
|
||||
<h3 class="be-section-title">💡 核心特点</h3>
|
||||
<h3 class="be-section-title">
|
||||
💡 核心特点
|
||||
</h3>
|
||||
<ul class="be-feature-list">
|
||||
<li
|
||||
v-for="(feature, idx) in currentStageData.features"
|
||||
|
||||
@@ -5,41 +5,72 @@
|
||||
<template>
|
||||
<div class="cache-demo">
|
||||
<div class="header">
|
||||
<div class="title">缓存命中率:速度与成本的杠杆</div>
|
||||
<div class="subtitle">调整命中率,观察平均延迟与数据库压力</div>
|
||||
<div class="title">
|
||||
缓存命中率:速度与成本的杠杆
|
||||
</div>
|
||||
<div class="subtitle">
|
||||
调整命中率,观察平均延迟与数据库压力
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="controls">
|
||||
<label>
|
||||
缓存命中率:<strong>{{ hitRatio }}%</strong>
|
||||
</label>
|
||||
<input v-model="hitRatio" type="range" min="0" max="100" step="1" />
|
||||
<input
|
||||
v-model="hitRatio"
|
||||
type="range"
|
||||
min="0"
|
||||
max="100"
|
||||
step="1"
|
||||
>
|
||||
<label class="toggle">
|
||||
<input v-model="cacheEnabled" type="checkbox" />
|
||||
<input
|
||||
v-model="cacheEnabled"
|
||||
type="checkbox"
|
||||
>
|
||||
启用缓存
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="metrics">
|
||||
<div class="metric-card">
|
||||
<div class="label">平均延迟</div>
|
||||
<div class="value">{{ avgLatency }} ms</div>
|
||||
<div class="label">
|
||||
平均延迟
|
||||
</div>
|
||||
<div class="value">
|
||||
{{ avgLatency }} ms
|
||||
</div>
|
||||
<div class="meter">
|
||||
<div class="bar" :style="{ width: latencyBar + '%' }"></div>
|
||||
<div
|
||||
class="bar"
|
||||
:style="{ width: latencyBar + '%' }"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="metric-card">
|
||||
<div class="label">数据库请求比例</div>
|
||||
<div class="value">{{ dbRate }}%</div>
|
||||
<div class="label">
|
||||
数据库请求比例
|
||||
</div>
|
||||
<div class="value">
|
||||
{{ dbRate }}%
|
||||
</div>
|
||||
<div class="meter">
|
||||
<div class="bar warn" :style="{ width: dbRate + '%' }"></div>
|
||||
<div
|
||||
class="bar warn"
|
||||
:style="{ width: dbRate + '%' }"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="legend">
|
||||
<div class="item"><span class="dot cache"></span>缓存命中</div>
|
||||
<div class="item"><span class="dot db"></span>数据库读取</div>
|
||||
<div class="item">
|
||||
<span class="dot cache" />缓存命中
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="dot db" />数据库读取
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -6,8 +6,12 @@
|
||||
<div class="cgi-demo">
|
||||
<div class="panel">
|
||||
<div class="panel-header">
|
||||
<div class="title">CGI 串行处理:排队效应</div>
|
||||
<div class="subtitle">请求越多,响应越慢</div>
|
||||
<div class="title">
|
||||
CGI 串行处理:排队效应
|
||||
</div>
|
||||
<div class="subtitle">
|
||||
请求越多,响应越慢
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="controls">
|
||||
@@ -20,36 +24,61 @@
|
||||
min="1"
|
||||
max="200"
|
||||
step="1"
|
||||
/>
|
||||
>
|
||||
|
||||
<div class="toggles">
|
||||
<label class="toggle">
|
||||
<input v-model="staticCache" type="checkbox" />
|
||||
<input
|
||||
v-model="staticCache"
|
||||
type="checkbox"
|
||||
>
|
||||
启用静态缓存 (减少脚本开销)
|
||||
</label>
|
||||
<button class="burst" @click="simulateBurst">模拟秒杀</button>
|
||||
<button
|
||||
class="burst"
|
||||
@click="simulateBurst"
|
||||
>
|
||||
模拟秒杀
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="stats">
|
||||
<div class="stat">
|
||||
<div class="label">平均响应时间</div>
|
||||
<div class="value">{{ avgResponse }} ms</div>
|
||||
<div class="label">
|
||||
平均响应时间
|
||||
</div>
|
||||
<div class="value">
|
||||
{{ avgResponse }} ms
|
||||
</div>
|
||||
<div class="meter">
|
||||
<div class="bar" :style="{ width: responseBar + '%' }"></div>
|
||||
<div
|
||||
class="bar"
|
||||
:style="{ width: responseBar + '%' }"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<div class="label">排队请求数</div>
|
||||
<div class="value">{{ queueLength }}</div>
|
||||
<div class="label">
|
||||
排队请求数
|
||||
</div>
|
||||
<div class="value">
|
||||
{{ queueLength }}
|
||||
</div>
|
||||
<div class="meter">
|
||||
<div class="bar warn" :style="{ width: queueBar + '%' }"></div>
|
||||
<div
|
||||
class="bar warn"
|
||||
:style="{ width: queueBar + '%' }"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="note">
|
||||
<span class="dot" :class="statusClass"></span>
|
||||
<span
|
||||
class="dot"
|
||||
:class="statusClass"
|
||||
/>
|
||||
<span>{{ statusText }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+66
-19
@@ -7,44 +7,91 @@
|
||||
</div>
|
||||
|
||||
<div class="docker-visualization">
|
||||
<div class="layer traditional" :class="{ active: showTraditional }" @click="showTraditional = true; showDocker = false">
|
||||
<div
|
||||
class="layer traditional"
|
||||
:class="{ active: showTraditional }"
|
||||
@click="showTraditional = true; showDocker = false"
|
||||
>
|
||||
<h5>传统部署</h5>
|
||||
<div class="server-stack">
|
||||
<div class="layer-item app">应用 A</div>
|
||||
<div class="layer-item conflict" v-if="showConflict">依赖冲突!</div>
|
||||
<div class="layer-item deps">依赖库 v1.0</div>
|
||||
<div class="layer-item os">操作系统</div>
|
||||
<div class="layer-item hardware">物理服务器</div>
|
||||
<div class="layer-item app">
|
||||
应用 A
|
||||
</div>
|
||||
<div
|
||||
v-if="showConflict"
|
||||
class="layer-item conflict"
|
||||
>
|
||||
依赖冲突!
|
||||
</div>
|
||||
<div class="layer-item deps">
|
||||
依赖库 v1.0
|
||||
</div>
|
||||
<div class="layer-item os">
|
||||
操作系统
|
||||
</div>
|
||||
<div class="layer-item hardware">
|
||||
物理服务器
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="vs-divider">VS</div>
|
||||
<div class="vs-divider">
|
||||
VS
|
||||
</div>
|
||||
|
||||
<div class="layer docker" :class="{ active: showDocker }" @click="showDocker = true; showTraditional = false">
|
||||
<div
|
||||
class="layer docker"
|
||||
:class="{ active: showDocker }"
|
||||
@click="showDocker = true; showTraditional = false"
|
||||
>
|
||||
<h5>Docker 容器</h5>
|
||||
<div class="docker-stack">
|
||||
<div class="containers">
|
||||
<div class="container-box">
|
||||
<div class="container-app">应用 A</div>
|
||||
<div class="container-deps">依赖 v1.0</div>
|
||||
<div class="container-app">
|
||||
应用 A
|
||||
</div>
|
||||
<div class="container-deps">
|
||||
依赖 v1.0
|
||||
</div>
|
||||
</div>
|
||||
<div class="container-box">
|
||||
<div class="container-app">应用 B</div>
|
||||
<div class="container-deps">依赖 v2.0</div>
|
||||
<div class="container-app">
|
||||
应用 B
|
||||
</div>
|
||||
<div class="container-deps">
|
||||
依赖 v2.0
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="docker-engine">Docker Engine</div>
|
||||
<div class="host-os">宿主机操作系统</div>
|
||||
<div class="hardware">物理服务器</div>
|
||||
<div class="docker-engine">
|
||||
Docker Engine
|
||||
</div>
|
||||
<div class="host-os">
|
||||
宿主机操作系统
|
||||
</div>
|
||||
<div class="hardware">
|
||||
物理服务器
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="benefits-grid">
|
||||
<div class="benefit-card" v-for="benefit in benefits" :key="benefit.title">
|
||||
<div class="benefit-icon">{{ benefit.icon }}</div>
|
||||
<div class="benefit-title">{{ benefit.title }}</div>
|
||||
<div class="benefit-desc">{{ benefit.desc }}</div>
|
||||
<div
|
||||
v-for="benefit in benefits"
|
||||
:key="benefit.title"
|
||||
class="benefit-card"
|
||||
>
|
||||
<div class="benefit-icon">
|
||||
{{ benefit.icon }}
|
||||
</div>
|
||||
<div class="benefit-title">
|
||||
{{ benefit.title }}
|
||||
</div>
|
||||
<div class="benefit-desc">
|
||||
{{ benefit.desc }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -13,18 +13,30 @@
|
||||
:class="{ active: currentStep === idx }"
|
||||
@click="currentStep = idx"
|
||||
>
|
||||
<div class="step-connector" v-if="idx > 0">
|
||||
<div class="connector-line"></div>
|
||||
<div
|
||||
v-if="idx > 0"
|
||||
class="step-connector"
|
||||
>
|
||||
<div class="connector-line" />
|
||||
</div>
|
||||
<div class="step-content">
|
||||
<div class="step-icon">{{ step.icon }}</div>
|
||||
<div class="step-era">{{ step.era }}</div>
|
||||
<div class="step-title">{{ step.title }}</div>
|
||||
<div class="step-icon">
|
||||
{{ step.icon }}
|
||||
</div>
|
||||
<div class="step-era">
|
||||
{{ step.era }}
|
||||
</div>
|
||||
<div class="step-title">
|
||||
{{ step.title }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="step-detail" v-if="currentStep !== null">
|
||||
<div
|
||||
v-if="currentStep !== null"
|
||||
class="step-detail"
|
||||
>
|
||||
<h5>{{ steps[currentStep].title }}</h5>
|
||||
<div class="detail-grid">
|
||||
<div class="detail-item">
|
||||
@@ -42,7 +54,11 @@
|
||||
</div>
|
||||
<div class="tools-list">
|
||||
<span class="tools-label">代表工具:</span>
|
||||
<span v-for="tool in steps[currentStep].tools" :key="tool" class="tool-tag">{{ tool }}</span>
|
||||
<span
|
||||
v-for="tool in steps[currentStep].tools"
|
||||
:key="tool"
|
||||
class="tool-tag"
|
||||
>{{ tool }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -14,16 +14,33 @@
|
||||
:class="{ active: currentStage === idx }"
|
||||
@click="currentStage = idx"
|
||||
>
|
||||
<div class="stage-era">{{ stage.era }}</div>
|
||||
<div class="stage-icon">{{ stage.icon }}</div>
|
||||
<div class="stage-name">{{ stage.name }}</div>
|
||||
<div class="stage-arch">{{ stage.arch }}</div>
|
||||
<div class="stage-era">
|
||||
{{ stage.era }}
|
||||
</div>
|
||||
<div class="stage-icon">
|
||||
{{ stage.icon }}
|
||||
</div>
|
||||
<div class="stage-name">
|
||||
{{ stage.name }}
|
||||
</div>
|
||||
<div class="stage-arch">
|
||||
{{ stage.arch }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="stage-detail" v-if="currentStage !== null">
|
||||
<Transition name="fade" mode="out-in">
|
||||
<div :key="currentStage" class="detail-panel">
|
||||
<div
|
||||
v-if="currentStage !== null"
|
||||
class="stage-detail"
|
||||
>
|
||||
<Transition
|
||||
name="fade"
|
||||
mode="out-in"
|
||||
>
|
||||
<div
|
||||
:key="currentStage"
|
||||
class="detail-panel"
|
||||
>
|
||||
<div class="detail-header">
|
||||
<span class="detail-icon">{{ stages[currentStage].icon }}</span>
|
||||
<h4>{{ stages[currentStage].restaurant }}</h4>
|
||||
@@ -40,7 +57,12 @@
|
||||
<div class="detail-section">
|
||||
<h5>⚡ 核心痛点</h5>
|
||||
<ul>
|
||||
<li v-for="(pain, i) in stages[currentStage].pains" :key="i">{{ pain }}</li>
|
||||
<li
|
||||
v-for="(pain, i) in stages[currentStage].pains"
|
||||
:key="i"
|
||||
>
|
||||
{{ pain }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -7,58 +7,99 @@
|
||||
|
||||
<div class="k8s-architecture">
|
||||
<div class="control-plane">
|
||||
<div class="plane-title">控制平面 (Control Plane)</div>
|
||||
<div class="plane-title">
|
||||
控制平面 (Control Plane)
|
||||
</div>
|
||||
<div class="components">
|
||||
<div class="component" v-for="comp in controlPlane" :key="comp.name"
|
||||
:class="{ active: activeComponent === comp.name }"
|
||||
@click="activeComponent = comp.name">
|
||||
<div class="comp-icon">{{ comp.icon }}</div>
|
||||
<div class="comp-name">{{ comp.name }}</div>
|
||||
<div class="comp-desc">{{ comp.desc }}</div>
|
||||
<div
|
||||
v-for="comp in controlPlane"
|
||||
:key="comp.name"
|
||||
class="component"
|
||||
:class="{ active: activeComponent === comp.name }"
|
||||
@click="activeComponent = comp.name"
|
||||
>
|
||||
<div class="comp-icon">
|
||||
{{ comp.icon }}
|
||||
</div>
|
||||
<div class="comp-name">
|
||||
{{ comp.name }}
|
||||
</div>
|
||||
<div class="comp-desc">
|
||||
{{ comp.desc }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="worker-nodes">
|
||||
<div class="plane-title">工作节点 (Worker Nodes)</div>
|
||||
<div class="plane-title">
|
||||
工作节点 (Worker Nodes)
|
||||
</div>
|
||||
<div class="nodes-container">
|
||||
<div class="node" v-for="node in workerNodes" :key="node.name"
|
||||
:class="{
|
||||
active: node.status === 'active',
|
||||
failed: node.status === 'failed',
|
||||
selected: selectedNode === node.name
|
||||
}"
|
||||
@click="selectNode(node.name)">
|
||||
<div
|
||||
v-for="node in workerNodes"
|
||||
:key="node.name"
|
||||
class="node"
|
||||
:class="{
|
||||
active: node.status === 'active',
|
||||
failed: node.status === 'failed',
|
||||
selected: selectedNode === node.name
|
||||
}"
|
||||
@click="selectNode(node.name)"
|
||||
>
|
||||
<div class="node-header">
|
||||
<span class="node-icon">{{ node.icon }}</span>
|
||||
<span class="node-name">{{ node.name }}</span>
|
||||
<span class="node-status" :class="node.status">{{ node.statusText }}</span>
|
||||
<span
|
||||
class="node-status"
|
||||
:class="node.status"
|
||||
>{{ node.statusText }}</span>
|
||||
</div>
|
||||
<div class="node-resources">
|
||||
<div class="resource">
|
||||
<span class="res-label">CPU:</span>
|
||||
<div class="res-bar">
|
||||
<div class="res-fill" :style="{ width: node.cpu + '%' }" :class="{ high: node.cpu > 80 }"></div>
|
||||
<div
|
||||
class="res-fill"
|
||||
:style="{ width: node.cpu + '%' }"
|
||||
:class="{ high: node.cpu > 80 }"
|
||||
/>
|
||||
</div>
|
||||
<span class="res-value">{{ node.cpu }}%</span>
|
||||
</div>
|
||||
<div class="resource">
|
||||
<span class="res-label">内存:</span>
|
||||
<div class="res-bar">
|
||||
<div class="res-fill" :style="{ width: node.memory + '%' }" :class="{ high: node.memory > 80 }"></div>
|
||||
<div
|
||||
class="res-fill"
|
||||
:style="{ width: node.memory + '%' }"
|
||||
:class="{ high: node.memory > 80 }"
|
||||
/>
|
||||
</div>
|
||||
<span class="res-value">{{ node.memory }}%</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="node-pods">
|
||||
<div class="pods-label">运行 Pod: {{ node.pods }} 个</div>
|
||||
<div class="pods-label">
|
||||
运行 Pod: {{ node.pods }} 个
|
||||
</div>
|
||||
<div class="pods-grid">
|
||||
<div v-for="n in Math.min(node.pods, 8)" :key="n" class="pod-dot" :class="{
|
||||
running: node.status === 'active',
|
||||
pending: node.status === 'pending',
|
||||
failed: node.status === 'failed'
|
||||
}"></div>
|
||||
<div v-if="node.pods > 8" class="pod-more">+{{ node.pods - 8 }}</div>
|
||||
<div
|
||||
v-for="n in Math.min(node.pods, 8)"
|
||||
:key="n"
|
||||
class="pod-dot"
|
||||
:class="{
|
||||
running: node.status === 'active',
|
||||
pending: node.status === 'pending',
|
||||
failed: node.status === 'failed'
|
||||
}"
|
||||
/>
|
||||
<div
|
||||
v-if="node.pods > 8"
|
||||
class="pod-more"
|
||||
>
|
||||
+{{ node.pods - 8 }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -67,14 +108,45 @@
|
||||
</div>
|
||||
|
||||
<div class="k8s-controls">
|
||||
<button class="control-btn" @click="simulateScheduling" :disabled="isScheduling">{{ isScheduling ? '调度中...' : '🚀 模拟 Pod 调度' }}</button>
|
||||
<button class="control-btn" @click="simulateScaling" :disabled="isScaling">{{ isScaling ? '扩容中...' : '📈 自动扩容' }}</button>
|
||||
<button class="control-btn danger" @click="simulateFailure" :disabled="isFailing">{{ isFailing ? '故障注入中...' : '💥 模拟节点故障' }}</button>
|
||||
<button class="control-btn" @click="resetCluster">🔄 重置集群</button>
|
||||
<button
|
||||
class="control-btn"
|
||||
:disabled="isScheduling"
|
||||
@click="simulateScheduling"
|
||||
>
|
||||
{{ isScheduling ? '调度中...' : '🚀 模拟 Pod 调度' }}
|
||||
</button>
|
||||
<button
|
||||
class="control-btn"
|
||||
:disabled="isScaling"
|
||||
@click="simulateScaling"
|
||||
>
|
||||
{{ isScaling ? '扩容中...' : '📈 自动扩容' }}
|
||||
</button>
|
||||
<button
|
||||
class="control-btn danger"
|
||||
:disabled="isFailing"
|
||||
@click="simulateFailure"
|
||||
>
|
||||
{{ isFailing ? '故障注入中...' : '💥 模拟节点故障' }}
|
||||
</button>
|
||||
<button
|
||||
class="control-btn"
|
||||
@click="resetCluster"
|
||||
>
|
||||
🔄 重置集群
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="k8s-logs" v-if="logs.length > 0">
|
||||
<div class="log-entry" v-for="(log, idx) in logs.slice(-5)" :key="idx" :class="log.level">
|
||||
<div
|
||||
v-if="logs.length > 0"
|
||||
class="k8s-logs"
|
||||
>
|
||||
<div
|
||||
v-for="(log, idx) in logs.slice(-5)"
|
||||
:key="idx"
|
||||
class="log-entry"
|
||||
:class="log.level"
|
||||
>
|
||||
<span class="log-time">{{ log.time }}</span>
|
||||
<span class="log-message">{{ log.message }}</span>
|
||||
</div>
|
||||
|
||||
+68
-23
@@ -5,65 +5,110 @@
|
||||
<template>
|
||||
<div class="microservice-latency-demo">
|
||||
<div class="header">
|
||||
<div class="title">微服务延迟:网络调用的代价</div>
|
||||
<div class="title">
|
||||
微服务延迟:网络调用的代价
|
||||
</div>
|
||||
<div class="subtitle">
|
||||
每次服务间调用都增加网络延迟,累积后响应时间变长
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="controls">
|
||||
<label
|
||||
>服务间调用次数:<strong>{{ callCount }}</strong></label
|
||||
<label>服务间调用次数:<strong>{{ callCount }}</strong></label>
|
||||
<input
|
||||
v-model="callCount"
|
||||
type="range"
|
||||
min="1"
|
||||
max="10"
|
||||
step="1"
|
||||
>
|
||||
<input v-model="callCount" type="range" min="1" max="10" step="1" />
|
||||
|
||||
<label
|
||||
>网络延迟:<strong>{{ networkLatency }} ms</strong></label
|
||||
<label>网络延迟:<strong>{{ networkLatency }} ms</strong></label>
|
||||
<input
|
||||
v-model="networkLatency"
|
||||
type="range"
|
||||
min="1"
|
||||
max="50"
|
||||
step="1"
|
||||
>
|
||||
<input v-model="networkLatency" type="range" min="1" max="50" step="1" />
|
||||
</div>
|
||||
|
||||
<div class="comparison">
|
||||
<div class="architecture monolith">
|
||||
<div class="arch-title">单体架构</div>
|
||||
<div class="arch-title">
|
||||
单体架构
|
||||
</div>
|
||||
<div class="arch-box">
|
||||
<div class="single-process">
|
||||
<div class="module">User</div>
|
||||
<div class="module">Order</div>
|
||||
<div class="module">Payment</div>
|
||||
<div class="module">
|
||||
User
|
||||
</div>
|
||||
<div class="module">
|
||||
Order
|
||||
</div>
|
||||
<div class="module">
|
||||
Payment
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="latency">
|
||||
<div class="latency-value">{{ monolithLatency }} ms</div>
|
||||
<div class="latency-label">内存调用(~0ms)</div>
|
||||
<div class="latency-value">
|
||||
{{ monolithLatency }} ms
|
||||
</div>
|
||||
<div class="latency-label">
|
||||
内存调用(~0ms)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="architecture microservices">
|
||||
<div class="arch-title">微服务架构</div>
|
||||
<div class="arch-title">
|
||||
微服务架构
|
||||
</div>
|
||||
<div class="arch-box">
|
||||
<div class="services">
|
||||
<div class="service">User Svc</div>
|
||||
<div class="network-arrow" v-if="callCount > 1">
|
||||
<div class="service">
|
||||
User Svc
|
||||
</div>
|
||||
<div
|
||||
v-if="callCount > 1"
|
||||
class="network-arrow"
|
||||
>
|
||||
⇄ {{ networkLatency }}ms
|
||||
</div>
|
||||
<div class="service">Order Svc</div>
|
||||
<div class="network-arrow" v-if="callCount > 2">
|
||||
<div class="service">
|
||||
Order Svc
|
||||
</div>
|
||||
<div
|
||||
v-if="callCount > 2"
|
||||
class="network-arrow"
|
||||
>
|
||||
⇄ {{ networkLatency }}ms
|
||||
</div>
|
||||
<div class="service">Payment Svc</div>
|
||||
<div class="service">
|
||||
Payment Svc
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="latency">
|
||||
<div class="latency-value high">{{ microLatency }} ms</div>
|
||||
<div class="latency-label">网络调用累积</div>
|
||||
<div class="latency-value high">
|
||||
{{ microLatency }} ms
|
||||
</div>
|
||||
<div class="latency-label">
|
||||
网络调用累积
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="insight">
|
||||
<div class="insight-icon" v-html="insightIcon"></div>
|
||||
<div class="insight-text">{{ insight }}</div>
|
||||
<div
|
||||
class="insight-icon"
|
||||
v-html="insightIcon"
|
||||
/>
|
||||
<div class="insight-text">
|
||||
{{ insight }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -16,7 +16,10 @@
|
||||
<div class="service-header">
|
||||
<span class="service-icon">{{ service.icon }}</span>
|
||||
<span class="service-name">{{ service.name }}</span>
|
||||
<span class="service-status" :class="service.status">{{ service.statusText }}</span>
|
||||
<span
|
||||
class="service-status"
|
||||
:class="service.status"
|
||||
>{{ service.statusText }}</span>
|
||||
</div>
|
||||
<div class="service-details">
|
||||
<div class="detail-row">
|
||||
@@ -38,18 +41,39 @@
|
||||
<div class="communication-flow">
|
||||
<h5>服务间通信链路</h5>
|
||||
<div class="flow-visualization">
|
||||
<div class="flow-step" v-for="(step, idx) in flowSteps" :key="idx"
|
||||
:class="{ active: currentFlowStep === idx, completed: currentFlowStep > idx }">
|
||||
<div class="step-number">{{ idx + 1 }}</div>
|
||||
<div
|
||||
v-for="(step, idx) in flowSteps"
|
||||
:key="idx"
|
||||
class="flow-step"
|
||||
:class="{ active: currentFlowStep === idx, completed: currentFlowStep > idx }"
|
||||
>
|
||||
<div class="step-number">
|
||||
{{ idx + 1 }}
|
||||
</div>
|
||||
<div class="step-content">
|
||||
<div class="step-service">{{ step.service }}</div>
|
||||
<div class="step-action">{{ step.action }}</div>
|
||||
<div class="step-service">
|
||||
{{ step.service }}
|
||||
</div>
|
||||
<div class="step-action">
|
||||
{{ step.action }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flow-controls">
|
||||
<button class="flow-btn" @click="startFlow" :disabled="isFlowRunning">开始流程</button>
|
||||
<button class="flow-btn" @click="resetFlow">重置</button>
|
||||
<button
|
||||
class="flow-btn"
|
||||
:disabled="isFlowRunning"
|
||||
@click="startFlow"
|
||||
>
|
||||
开始流程
|
||||
</button>
|
||||
<button
|
||||
class="flow-btn"
|
||||
@click="resetFlow"
|
||||
>
|
||||
重置
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -7,8 +7,13 @@
|
||||
</div>
|
||||
|
||||
<div class="monolith-diagram">
|
||||
<div class="monolith-box" :class="{ crashed: hasCrashed }">
|
||||
<div class="monolith-header">单体应用进程</div>
|
||||
<div
|
||||
class="monolith-box"
|
||||
:class="{ crashed: hasCrashed }"
|
||||
>
|
||||
<div class="monolith-header">
|
||||
单体应用进程
|
||||
</div>
|
||||
<div class="modules-container">
|
||||
<div
|
||||
v-for="module in modules"
|
||||
@@ -17,14 +22,27 @@
|
||||
:class="{ active: activeModule === module.name, crashed: crashedModule === module.name }"
|
||||
@click="triggerModule(module.name)"
|
||||
>
|
||||
<div class="module-icon">{{ module.icon }}</div>
|
||||
<div class="module-name">{{ module.name }}</div>
|
||||
<div class="module-status" :class="module.status">{{ module.statusText }}</div>
|
||||
<div class="module-icon">
|
||||
{{ module.icon }}
|
||||
</div>
|
||||
<div class="module-name">
|
||||
{{ module.name }}
|
||||
</div>
|
||||
<div
|
||||
class="module-status"
|
||||
:class="module.status"
|
||||
>
|
||||
{{ module.statusText }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="shared-db">
|
||||
<div class="db-icon">🗄️</div>
|
||||
<div class="db-label">共享数据库</div>
|
||||
<div class="db-icon">
|
||||
🗄️
|
||||
</div>
|
||||
<div class="db-label">
|
||||
共享数据库
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -43,9 +61,24 @@
|
||||
</div>
|
||||
|
||||
<div class="controls">
|
||||
<button class="control-btn" @click="simulateNormalRequest">正常请求</button>
|
||||
<button class="control-btn danger" @click="simulateCrash">模拟模块故障</button>
|
||||
<button class="control-btn" @click="reset">重置</button>
|
||||
<button
|
||||
class="control-btn"
|
||||
@click="simulateNormalRequest"
|
||||
>
|
||||
正常请求
|
||||
</button>
|
||||
<button
|
||||
class="control-btn danger"
|
||||
@click="simulateCrash"
|
||||
>
|
||||
模拟模块故障
|
||||
</button>
|
||||
<button
|
||||
class="control-btn"
|
||||
@click="reset"
|
||||
>
|
||||
重置
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="info-box">
|
||||
|
||||
+46
-12
@@ -5,13 +5,19 @@
|
||||
<template>
|
||||
<div class="release-demo">
|
||||
<div class="header">
|
||||
<div class="title">单体发布:牵一发而动全身</div>
|
||||
<div class="subtitle">选择修改范围,看看“爆炸半径”</div>
|
||||
<div class="title">
|
||||
单体发布:牵一发而动全身
|
||||
</div>
|
||||
<div class="subtitle">
|
||||
选择修改范围,看看“爆炸半径”
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<div class="modules">
|
||||
<div class="section-title">本次改动涉及</div>
|
||||
<div class="section-title">
|
||||
本次改动涉及
|
||||
</div>
|
||||
<div class="module-grid">
|
||||
<button
|
||||
v-for="module in modules"
|
||||
@@ -28,31 +34,59 @@
|
||||
<label>
|
||||
改动规模:<strong>{{ changeSizeLabel }}</strong>
|
||||
</label>
|
||||
<input v-model="changeSize" type="range" min="1" max="5" step="1" />
|
||||
<input
|
||||
v-model="changeSize"
|
||||
type="range"
|
||||
min="1"
|
||||
max="5"
|
||||
step="1"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="result">
|
||||
<div class="risk-meter">
|
||||
<div class="risk-title">故障概率</div>
|
||||
<div class="risk-value">{{ riskPercent }}%</div>
|
||||
<div class="risk-title">
|
||||
故障概率
|
||||
</div>
|
||||
<div class="risk-value">
|
||||
{{ riskPercent }}%
|
||||
</div>
|
||||
<div class="meter">
|
||||
<div class="bar" :style="{ width: riskPercent + '%' }"></div>
|
||||
<div
|
||||
class="bar"
|
||||
:style="{ width: riskPercent + '%' }"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="deploy-btn" @click="deployRelease">模拟发布</button>
|
||||
<div class="status" :class="deployStatusClass">
|
||||
<button
|
||||
class="deploy-btn"
|
||||
@click="deployRelease"
|
||||
>
|
||||
模拟发布
|
||||
</button>
|
||||
<div
|
||||
class="status"
|
||||
:class="deployStatusClass"
|
||||
>
|
||||
{{ deployStatus }}
|
||||
</div>
|
||||
|
||||
<div class="history">
|
||||
<div class="section-title">最近 3 次发布</div>
|
||||
<div class="section-title">
|
||||
最近 3 次发布
|
||||
</div>
|
||||
<ul>
|
||||
<li v-for="(item, index) in deployHistory" :key="index">
|
||||
<li
|
||||
v-for="(item, index) in deployHistory"
|
||||
:key="index"
|
||||
>
|
||||
{{ item }}
|
||||
</li>
|
||||
<li v-if="deployHistory.length === 0">暂无记录</li>
|
||||
<li v-if="deployHistory.length === 0">
|
||||
暂无记录
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+40
-12
@@ -1,23 +1,43 @@
|
||||
<template>
|
||||
<div class="monolith-microservice-demo">
|
||||
<div class="controls">
|
||||
<button class="action-btn crash-btn" @click="triggerCrash">
|
||||
<button
|
||||
class="action-btn crash-btn"
|
||||
@click="triggerCrash"
|
||||
>
|
||||
💥 Simulate Order Service Crash
|
||||
</button>
|
||||
<button class="action-btn reset-btn" @click="reset">🔄 Reset</button>
|
||||
<button
|
||||
class="action-btn reset-btn"
|
||||
@click="reset"
|
||||
>
|
||||
🔄 Reset
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="comparison-view">
|
||||
<!-- Monolith -->
|
||||
<div class="architecture-block monolith">
|
||||
<div class="arch-header">Monolith Architecture</div>
|
||||
<div class="server-container" :class="{ crashed: monolithCrashed }">
|
||||
<div class="arch-header">
|
||||
Monolith Architecture
|
||||
</div>
|
||||
<div
|
||||
class="server-container"
|
||||
:class="{ crashed: monolithCrashed }"
|
||||
>
|
||||
<div class="process-box">
|
||||
<div class="module user">User</div>
|
||||
<div class="module order" :class="{ error: monolithCrashed }">
|
||||
<div class="module user">
|
||||
User
|
||||
</div>
|
||||
<div
|
||||
class="module order"
|
||||
:class="{ error: monolithCrashed }"
|
||||
>
|
||||
Order
|
||||
</div>
|
||||
<div class="module pay">Payment</div>
|
||||
<div class="module pay">
|
||||
Payment
|
||||
</div>
|
||||
</div>
|
||||
<div class="status-indicator">
|
||||
Status:
|
||||
@@ -32,19 +52,27 @@
|
||||
|
||||
<!-- Microservices -->
|
||||
<div class="architecture-block microservices">
|
||||
<div class="arch-header">Microservices Architecture</div>
|
||||
<div class="arch-header">
|
||||
Microservices Architecture
|
||||
</div>
|
||||
<div class="services-container">
|
||||
<div class="service-box user">
|
||||
<span>User Svc</span>
|
||||
<div class="dot green"></div>
|
||||
<div class="dot green" />
|
||||
</div>
|
||||
<div class="service-box order" :class="{ crashed: microCrashed }">
|
||||
<div
|
||||
class="service-box order"
|
||||
:class="{ crashed: microCrashed }"
|
||||
>
|
||||
<span>Order Svc</span>
|
||||
<div class="dot" :class="microCrashed ? 'red' : 'green'"></div>
|
||||
<div
|
||||
class="dot"
|
||||
:class="microCrashed ? 'red' : 'green'"
|
||||
/>
|
||||
</div>
|
||||
<div class="service-box pay">
|
||||
<span>Payment Svc</span>
|
||||
<div class="dot green"></div>
|
||||
<div class="dot green" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="status-indicator">
|
||||
|
||||
@@ -8,7 +8,9 @@
|
||||
|
||||
<div class="demo-stage">
|
||||
<div class="client-zone">
|
||||
<div class="zone-title">👤 用户浏览器</div>
|
||||
<div class="zone-title">
|
||||
👤 用户浏览器
|
||||
</div>
|
||||
<div class="request-queue">
|
||||
<div
|
||||
v-for="(req, idx) in pendingRequests"
|
||||
@@ -30,7 +32,10 @@
|
||||
</div>
|
||||
|
||||
<div class="connection-zone">
|
||||
<div class="network-line" :class="{ busy: isProcessing }">
|
||||
<div
|
||||
class="network-line"
|
||||
:class="{ busy: isProcessing }"
|
||||
>
|
||||
<div class="packets">
|
||||
<div
|
||||
v-for="pkt in packets"
|
||||
@@ -43,27 +48,35 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="latency-display" v-if="currentLatency > 0">
|
||||
<div
|
||||
v-if="currentLatency > 0"
|
||||
class="latency-display"
|
||||
>
|
||||
⏱️ {{ currentLatency }}ms
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="server-zone">
|
||||
<div class="zone-title">🖥️ CGI 服务器</div>
|
||||
<div class="zone-title">
|
||||
🖥️ CGI 服务器
|
||||
</div>
|
||||
<div class="server-status">
|
||||
<div
|
||||
class="status-indicator"
|
||||
:class="{ processing: isProcessing }"
|
||||
>
|
||||
<span class="status-dot"></span>
|
||||
<span class="status-dot" />
|
||||
<span class="status-text">{{ serverStatus }}</span>
|
||||
</div>
|
||||
<div class="cpu-usage" v-if="isProcessing">
|
||||
<div
|
||||
v-if="isProcessing"
|
||||
class="cpu-usage"
|
||||
>
|
||||
<div class="cpu-bar">
|
||||
<div
|
||||
class="cpu-fill"
|
||||
:style="{ width: cpuUsage + '%' }"
|
||||
></div>
|
||||
/>
|
||||
</div>
|
||||
<span class="cpu-text">CPU: {{ cpuUsage }}%</span>
|
||||
</div>
|
||||
@@ -79,7 +92,7 @@
|
||||
<div
|
||||
class="proc-bar"
|
||||
:style="{ width: proc.progress + '%' }"
|
||||
></div>
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+50
-13
@@ -6,25 +6,58 @@
|
||||
</div>
|
||||
|
||||
<div class="strategies">
|
||||
<div class="strategy-card" :class="{ active: activeStrategy === 'vertical' }" @click="activeStrategy = 'vertical'">
|
||||
<div class="strategy-icon">📦</div>
|
||||
<div class="strategy-name">垂直扩展</div>
|
||||
<div class="strategy-desc">买更强的机器</div>
|
||||
<div
|
||||
class="strategy-card"
|
||||
:class="{ active: activeStrategy === 'vertical' }"
|
||||
@click="activeStrategy = 'vertical'"
|
||||
>
|
||||
<div class="strategy-icon">
|
||||
📦
|
||||
</div>
|
||||
<div class="strategy-name">
|
||||
垂直扩展
|
||||
</div>
|
||||
<div class="strategy-desc">
|
||||
买更强的机器
|
||||
</div>
|
||||
<div class="visual-vertical">
|
||||
<div class="server" :class="{ scale: activeStrategy === 'vertical' }">
|
||||
<div class="cpu">CPU</div>
|
||||
<div class="memory">内存</div>
|
||||
<div
|
||||
class="server"
|
||||
:class="{ scale: activeStrategy === 'vertical' }"
|
||||
>
|
||||
<div class="cpu">
|
||||
CPU
|
||||
</div>
|
||||
<div class="memory">
|
||||
内存
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="strategy-card" :class="{ active: activeStrategy === 'horizontal' }" @click="activeStrategy = 'horizontal'">
|
||||
<div class="strategy-icon">🔄</div>
|
||||
<div class="strategy-name">水平扩展</div>
|
||||
<div class="strategy-desc">加更多机器</div>
|
||||
<div
|
||||
class="strategy-card"
|
||||
:class="{ active: activeStrategy === 'horizontal' }"
|
||||
@click="activeStrategy = 'horizontal'"
|
||||
>
|
||||
<div class="strategy-icon">
|
||||
🔄
|
||||
</div>
|
||||
<div class="strategy-name">
|
||||
水平扩展
|
||||
</div>
|
||||
<div class="strategy-desc">
|
||||
加更多机器
|
||||
</div>
|
||||
<div class="visual-horizontal">
|
||||
<div class="servers">
|
||||
<div class="server-mini" v-for="n in 4" :key="n" :class="{ active: activeStrategy === 'horizontal' && n <= serverCount }" :style="{ animationDelay: (n * 0.1) + 's' }"></div>
|
||||
<div
|
||||
v-for="n in 4"
|
||||
:key="n"
|
||||
class="server-mini"
|
||||
:class="{ active: activeStrategy === 'horizontal' && n <= serverCount }"
|
||||
:style="{ animationDelay: (n * 0.1) + 's' }"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -36,7 +69,11 @@
|
||||
<span>垂直扩展</span>
|
||||
<span>水平扩展</span>
|
||||
</div>
|
||||
<div class="table-row" v-for="item in comparisonData" :key="item.dim">
|
||||
<div
|
||||
v-for="item in comparisonData"
|
||||
:key="item.dim"
|
||||
class="table-row"
|
||||
>
|
||||
<span>{{ item.dim }}</span>
|
||||
<span :class="{ better: item.verticalBetter }">{{ item.vertical }}</span>
|
||||
<span :class="{ better: item.horizontalBetter }">{{ item.horizontal }}</span>
|
||||
|
||||
+46
-13
@@ -5,8 +5,12 @@
|
||||
<template>
|
||||
<div class="serverless-demo">
|
||||
<div class="header">
|
||||
<div class="title">Serverless:按需付费 + 自动扩缩</div>
|
||||
<div class="subtitle">调整调用量与耗时,比较固定服务器成本</div>
|
||||
<div class="title">
|
||||
Serverless:按需付费 + 自动扩缩
|
||||
</div>
|
||||
<div class="subtitle">
|
||||
调整调用量与耗时,比较固定服务器成本
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="controls">
|
||||
@@ -20,39 +24,68 @@
|
||||
min="0"
|
||||
max="5000000"
|
||||
step="50000"
|
||||
/>
|
||||
>
|
||||
</div>
|
||||
<div class="control">
|
||||
<label>
|
||||
平均耗时:<strong>{{ durationMs }} ms</strong>
|
||||
</label>
|
||||
<input v-model="durationMs" type="range" min="20" max="800" step="10" />
|
||||
<input
|
||||
v-model="durationMs"
|
||||
type="range"
|
||||
min="20"
|
||||
max="800"
|
||||
step="10"
|
||||
>
|
||||
</div>
|
||||
<div class="control">
|
||||
<label>
|
||||
峰值并发:<strong>{{ peakRps }}</strong> rps
|
||||
</label>
|
||||
<input v-model="peakRps" type="range" min="10" max="8000" step="50" />
|
||||
<input
|
||||
v-model="peakRps"
|
||||
type="range"
|
||||
min="10"
|
||||
max="8000"
|
||||
step="50"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cards">
|
||||
<div class="card">
|
||||
<div class="card-title">Serverless 估算</div>
|
||||
<div class="card-value">${{ serverlessCost }}</div>
|
||||
<div class="card-desc">按量计费(示意)</div>
|
||||
<div class="card-title">
|
||||
Serverless 估算
|
||||
</div>
|
||||
<div class="card-value">
|
||||
${{ serverlessCost }}
|
||||
</div>
|
||||
<div class="card-desc">
|
||||
按量计费(示意)
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-title">固定服务器</div>
|
||||
<div class="card-value">${{ serverCost }}</div>
|
||||
<div class="card-desc">需预留 {{ requiredServers }} 台服务器</div>
|
||||
<div class="card-title">
|
||||
固定服务器
|
||||
</div>
|
||||
<div class="card-value">
|
||||
${{ serverCost }}
|
||||
</div>
|
||||
<div class="card-desc">
|
||||
需预留 {{ requiredServers }} 台服务器
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="autoscale">
|
||||
<div class="label">扩缩容状态</div>
|
||||
<div class="label">
|
||||
扩缩容状态
|
||||
</div>
|
||||
<div class="scale-bar">
|
||||
<div class="scale" :style="{ width: scalePercent + '%' }"></div>
|
||||
<div
|
||||
class="scale"
|
||||
:style="{ width: scalePercent + '%' }"
|
||||
/>
|
||||
</div>
|
||||
<div class="scale-text">
|
||||
{{ scaleHint }}
|
||||
|
||||
@@ -7,11 +7,29 @@
|
||||
|
||||
<div class="serverless-visualization">
|
||||
<div class="function-grid">
|
||||
<div v-for="func in functions" :key="func.name" class="function-card" :class="{ active: func.state === 'running', cold: func.state === 'cold', warming: func.state === 'warming' }" @click="triggerFunction(func.name)">
|
||||
<div class="function-icon">{{ func.icon }}</div>
|
||||
<div class="function-name">{{ func.name }}</div>
|
||||
<div class="function-state" :class="func.state">{{ stateText(func.state) }}</div>
|
||||
<div class="function-metrics" v-if="func.invocations > 0">
|
||||
<div
|
||||
v-for="func in functions"
|
||||
:key="func.name"
|
||||
class="function-card"
|
||||
:class="{ active: func.state === 'running', cold: func.state === 'cold', warming: func.state === 'warming' }"
|
||||
@click="triggerFunction(func.name)"
|
||||
>
|
||||
<div class="function-icon">
|
||||
{{ func.icon }}
|
||||
</div>
|
||||
<div class="function-name">
|
||||
{{ func.name }}
|
||||
</div>
|
||||
<div
|
||||
class="function-state"
|
||||
:class="func.state"
|
||||
>
|
||||
{{ stateText(func.state) }}
|
||||
</div>
|
||||
<div
|
||||
v-if="func.invocations > 0"
|
||||
class="function-metrics"
|
||||
>
|
||||
<span>调用: {{ func.invocations }}</span>
|
||||
<span>平均: {{ func.avgDuration }}ms</span>
|
||||
</div>
|
||||
@@ -19,7 +37,9 @@
|
||||
</div>
|
||||
|
||||
<div class="auto-scaling-panel">
|
||||
<div class="scaling-title">自动扩缩容状态</div>
|
||||
<div class="scaling-title">
|
||||
自动扩缩容状态
|
||||
</div>
|
||||
<div class="scaling-metrics">
|
||||
<div class="metric">
|
||||
<span class="metric-label">并发请求:</span>
|
||||
@@ -35,15 +55,29 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="scaling-chart">
|
||||
<div v-for="(point, idx) in scalingHistory" :key="idx" class="chart-bar" :style="{ height: point + '%' }" :class="{ high: point > 70 }"></div>
|
||||
<div
|
||||
v-for="(point, idx) in scalingHistory"
|
||||
:key="idx"
|
||||
class="chart-bar"
|
||||
:style="{ height: point + '%' }"
|
||||
:class="{ high: point > 70 }"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="traffic-simulator">
|
||||
<div class="simulator-title">流量模拟器</div>
|
||||
<div class="simulator-title">
|
||||
流量模拟器
|
||||
</div>
|
||||
<div class="traffic-patterns">
|
||||
<button v-for="pattern in trafficPatterns" :key="pattern.name" class="pattern-btn" :class="{ active: currentPattern === pattern.name }" @click="applyPattern(pattern)">
|
||||
<button
|
||||
v-for="pattern in trafficPatterns"
|
||||
:key="pattern.name"
|
||||
class="pattern-btn"
|
||||
:class="{ active: currentPattern === pattern.name }"
|
||||
@click="applyPattern(pattern)"
|
||||
>
|
||||
<span class="pattern-icon">{{ pattern.icon }}</span>
|
||||
<span class="pattern-name">{{ pattern.name }}</span>
|
||||
<span class="pattern-desc">{{ pattern.desc }}</span>
|
||||
|
||||
+10
-4
@@ -15,8 +15,8 @@
|
||||
@click="activeEra = idx"
|
||||
>
|
||||
<div class="era-marker">
|
||||
<div class="era-dot"></div>
|
||||
<div class="era-line"></div>
|
||||
<div class="era-dot" />
|
||||
<div class="era-line" />
|
||||
</div>
|
||||
|
||||
<div class="era-content">
|
||||
@@ -27,8 +27,14 @@
|
||||
</div>
|
||||
|
||||
<div class="tech-categories">
|
||||
<div class="category" v-for="(cat, cIdx) in era.categories" :key="cIdx">
|
||||
<div class="category-name">{{ cat.name }}</div>
|
||||
<div
|
||||
v-for="(cat, cIdx) in era.categories"
|
||||
:key="cIdx"
|
||||
class="category"
|
||||
>
|
||||
<div class="category-name">
|
||||
{{ cat.name }}
|
||||
</div>
|
||||
<div class="tech-tags">
|
||||
<span
|
||||
v-for="(tech, tIdx) in cat.techs"
|
||||
|
||||
Reference in New Issue
Block a user