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:
sanbuphy
2026-02-18 17:38:10 +08:00
parent 8b01686e68
commit 0eba9e87e9
456 changed files with 28450 additions and 9677 deletions
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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">
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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"