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
@@ -15,10 +15,10 @@
<button
v-for="(step, index) in steps"
:key="step.id"
@click="goToStep(index)"
class="step-chip"
:class="{ active: currentStep === index, completed: currentStep > index }"
:disabled="isAutoPlaying"
@click="goToStep(index)"
>
<span class="chip-num">{{ index + 1 }}</span>
<span class="chip-name">{{ step.shortName }}</span>
@@ -35,12 +35,24 @@
<span class="col-title">收到的代码</span>
</div>
<div class="code-preview">
<div class="code-line">&lt;div class="box"&gt;</div>
<div class="code-line indent">Hello</div>
<div class="code-line">&lt;/div&gt;</div>
<div class="code-line style-tag">&lt;style&gt;</div>
<div class="code-line indent">.box { bg: blue }</div>
<div class="code-line style-tag">&lt;/style&gt;</div>
<div class="code-line">
&lt;div class="box"&gt;
</div>
<div class="code-line indent">
Hello
</div>
<div class="code-line">
&lt;/div&gt;
</div>
<div class="code-line style-tag">
&lt;style&gt;
</div>
<div class="code-line indent">
.box { bg: blue }
</div>
<div class="code-line style-tag">
&lt;/style&gt;
</div>
</div>
</div>
@@ -53,60 +65,134 @@
<div class="process-stage">
<!-- 步骤展示 -->
<transition name="fade" mode="out-in">
<div :key="currentStep" class="step-content">
<transition
name="fade"
mode="out-in"
>
<div
:key="currentStep"
class="step-content"
>
<div class="step-visual">
<!-- 1. HTML解析 -->
<div v-if="currentStep === 0" class="visual-tree">
<div class="tree-node root">html</div>
<div class="tree-line"></div>
<div class="tree-node body">body</div>
<div class="tree-line"></div>
<div class="tree-node div highlight">div.box</div>
<div
v-if="currentStep === 0"
class="visual-tree"
>
<div class="tree-node root">
html
</div>
<div class="tree-line">
</div>
<div class="tree-node body">
body
</div>
<div class="tree-line">
</div>
<div class="tree-node div highlight">
div.box
</div>
</div>
<!-- 2. CSS解析 -->
<div v-else-if="currentStep === 1" class="visual-css">
<div
v-else-if="currentStep === 1"
class="visual-css"
>
<div class="css-card">
<span class="selector">.box</span>
<div class="rule">background: <span class="value">blue</span></div>
<div class="rule">
background: <span class="value">blue</span>
</div>
</div>
</div>
<!-- 3. 合并渲染树 -->
<div v-else-if="currentStep === 2" class="visual-combine">
<div class="combine-item dom">DOM树</div>
<div class="combine-plus">+</div>
<div class="combine-item css">CSS树</div>
<div class="combine-arrow"></div>
<div class="combine-result">渲染树</div>
<div
v-else-if="currentStep === 2"
class="visual-combine"
>
<div class="combine-item dom">
DOM树
</div>
<div class="combine-plus">
+
</div>
<div class="combine-item css">
CSS树
</div>
<div class="combine-arrow">
</div>
<div class="combine-result">
渲染树
</div>
</div>
<!-- 4. 布局计算 -->
<div v-else-if="currentStep === 3" class="visual-layout">
<div class="layout-box" :class="{ measured: isMeasured }">
<span class="measure-label" v-if="isMeasured">100px × 100px</span>
<div class="ruler-h" v-if="isMeasured"></div>
<div class="ruler-v" v-if="isMeasured"></div>
<div
v-else-if="currentStep === 3"
class="visual-layout"
>
<div
class="layout-box"
:class="{ measured: isMeasured }"
>
<span
v-if="isMeasured"
class="measure-label"
>100px × 100px</span>
<div
v-if="isMeasured"
class="ruler-h"
/>
<div
v-if="isMeasured"
class="ruler-v"
/>
</div>
</div>
<!-- 5. 绘制 -->
<div v-else-if="currentStep === 4" class="visual-paint">
<div class="paint-layer bg" :class="{ painted: isPainted }">背景层</div>
<div class="paint-layer text" :class="{ painted: isPainted }">文字层</div>
<div
v-else-if="currentStep === 4"
class="visual-paint"
>
<div
class="paint-layer bg"
:class="{ painted: isPainted }"
>
背景层
</div>
<div
class="paint-layer text"
:class="{ painted: isPainted }"
>
文字层
</div>
</div>
<!-- 6. 合成 -->
<div v-else class="visual-final">
<div class="final-box">Hello</div>
<div class="check-mark"></div>
<div
v-else
class="visual-final"
>
<div class="final-box">
Hello
</div>
<div class="check-mark">
</div>
</div>
</div>
<div class="step-desc">
<span class="step-badge">{{ currentStep + 1 }}. {{ steps[currentStep].name }}</span>
<p class="step-text">{{ steps[currentStep].desc }}</p>
<p class="step-text">
{{ steps[currentStep].desc }}
</p>
</div>
</div>
</transition>
@@ -121,21 +207,30 @@
</div>
<div class="screen-preview">
<div class="browser-toolbar">
<span class="dot red"></span>
<span class="dot yellow"></span>
<span class="dot green"></span>
<span class="dot red" />
<span class="dot yellow" />
<span class="dot green" />
</div>
<div class="viewport">
<transition name="scale">
<div v-if="currentStep >= 5" class="final-render">
<div
v-if="currentStep >= 5"
class="final-render"
>
Hello
</div>
<div v-else-if="currentStep >= 4" class="skeleton-render">
<div class="sk-box"></div>
<div
v-else-if="currentStep >= 4"
class="skeleton-render"
>
<div class="sk-box" />
</div>
</transition>
<div v-if="currentStep < 4" class="loading-spinner">
<div class="spinner"></div>
<div
v-if="currentStep < 4"
class="loading-spinner"
>
<div class="spinner" />
</div>
</div>
</div>
@@ -147,32 +242,56 @@
<div class="analogy-bar">
<span class="analogy-icon">💡</span>
<span class="analogy-text">
<strong>核心机制</strong> <span v-html="steps[currentStep].analogy"></span>
<strong>核心机制</strong> <span v-html="steps[currentStep].analogy" />
</span>
</div>
<div class="action-buttons">
<button class="ctrl-btn" @click="prevStep" :disabled="currentStep <= 0 || isAutoPlaying">
<button
class="ctrl-btn"
:disabled="currentStep <= 0 || isAutoPlaying"
@click="prevStep"
>
上一步
</button>
<button class="ctrl-btn primary" @click="toggleAutoPlay">
<button
class="ctrl-btn primary"
@click="toggleAutoPlay"
>
{{ isAutoPlaying ? '暂停演示' : '自动演示' }}
</button>
<button class="ctrl-btn" @click="nextStep" :disabled="currentStep >= steps.length - 1 || isAutoPlaying">
<button
class="ctrl-btn"
:disabled="currentStep >= steps.length - 1 || isAutoPlaying"
@click="nextStep"
>
下一步
</button>
</div>
</div>
<!-- 技术答疑面板 -->
<div class="qa-panel" v-if="steps[currentStep].qa">
<div
v-if="steps[currentStep].qa"
class="qa-panel"
>
<div class="qa-header">
{{ steps[currentStep].qa.title }}
</div>
<div class="qa-content">
<div v-for="(item, idx) in steps[currentStep].qa.content" :key="idx" class="qa-item">
<div class="qa-q" v-html="'Q: ' + item.q"></div>
<div class="qa-a" v-html="item.a"></div>
<div
v-for="(item, idx) in steps[currentStep].qa.content"
:key="idx"
class="qa-item"
>
<div
class="qa-q"
v-html="'Q: ' + item.q"
/>
<div
class="qa-a"
v-html="item.a"
/>
</div>
</div>
</div>
@@ -18,8 +18,16 @@
<div class="target-select">
<span class="label">目标</span>
<select v-model="selectedTargetIndex" :disabled="isSearching" @change="reset">
<option v-for="(t, i) in targets" :key="t.name" :value="i">
<select
v-model="selectedTargetIndex"
:disabled="isSearching"
@change="reset"
>
<option
v-for="(t, i) in targets"
:key="t.name"
:value="i"
>
{{ t.name }} ({{ t.domain }})
</option>
</select>
@@ -27,23 +35,23 @@
<div class="actions">
<button
class="action-btn primary"
v-if="!isSearching && !isFinished"
class="action-btn primary"
@click="startAutoSearch"
v-if="!isSearching && !isFinished"
>
开始寻址
</button>
<button
class="action-btn secondary"
v-if="isSearching && !autoPlay"
class="action-btn secondary"
@click="nextStep"
v-if="isSearching && !autoPlay"
>
下一步
</button>
<button
class="action-btn outline"
v-if="isFinished || isSearching"
class="action-btn outline"
@click="reset"
v-if="isFinished || isSearching"
>
重置
</button>
@@ -52,15 +60,24 @@
<!-- 进度条/状态展示 -->
<div class="status-bar">
<div v-if="!isSearching && !isFinished" class="status-text">
<div
v-if="!isSearching && !isFinished"
class="status-text"
>
<span class="icon">👋</span>
准备出发去问问 <strong>{{ targets[selectedTargetIndex].domain }}</strong> IP 是多少
</div>
<div v-else-if="isSearching" class="status-text running">
<div
v-else-if="isSearching"
class="status-text running"
>
<span class="icon spin"></span>
正在询问{{ queryLevels[currentStep]?.analogyName }}...
</div>
<div v-else class="status-text success">
<div
v-else
class="status-text success"
>
<span class="icon"></span>
找到了IP 地址是<strong>{{ targets[selectedTargetIndex].ip }}</strong>
</div>
@@ -79,13 +96,21 @@
}"
@click="jumpToStep(index)"
>
<div class="step-icon-box" :style="{ '--step-color': level.color }">
<div
class="step-icon-box"
:style="{ '--step-color': level.color }"
>
<span class="step-icon">{{ level.analogyIcon }}</span>
</div>
<div class="step-label">{{ level.analogyName }}</div>
<div class="step-label">
{{ level.analogyName }}
</div>
<!-- 连接线 -->
<div class="step-line" v-if="index < queryLevels.length - 1"></div>
<div
v-if="index < queryLevels.length - 1"
class="step-line"
/>
</div>
</div>
@@ -93,20 +118,35 @@
<div class="info-panels">
<!-- 左侧生活场景 -->
<div class="detail-panel analogy-panel">
<transition name="fade" mode="out-in">
<div v-if="currentStep >= 0" class="panel-content" :key="currentStep">
<div class="panel-header" :style="{ color: currentLevel.color }">
<transition
name="fade"
mode="out-in"
>
<div
v-if="currentStep >= 0"
:key="currentStep"
class="panel-content"
>
<div
class="panel-header"
:style="{ color: currentLevel.color }"
>
<span class="header-icon">{{ currentLevel.analogyIcon }}</span>
<span class="header-title">{{ currentLevel.analogyName }} ({{ currentLevel.techName }})</span>
</div>
<div class="panel-body">
<p class="analogy-text">{{ currentLevel.analogyAction }}</p>
<p class="analogy-text">
{{ currentLevel.analogyAction }}
</p>
<div class="tech-hint-badge">
{{ currentLevel.techAction }}
</div>
</div>
</div>
<div v-else class="panel-placeholder">
<div
v-else
class="panel-placeholder"
>
<span>生活场景视角</span>
</div>
</transition>
@@ -116,12 +156,21 @@
<div class="detail-panel terminal-panel">
<div class="terminal-header">
<div class="terminal-dots">
<span></span><span></span><span></span>
<span /><span /><span />
</div>
<div class="terminal-title">
Terminal
</div>
<div class="terminal-title">Terminal</div>
</div>
<transition name="fade" mode="out-in">
<div v-if="currentStep >= 0" class="terminal-body" :key="currentStep">
<transition
name="fade"
mode="out-in"
>
<div
v-if="currentStep >= 0"
:key="currentStep"
class="terminal-body"
>
<div class="cmd-line">
<span class="prompt">$</span>
<span class="cmd">{{ formatText(currentLevel.techCommand) }}</span>
@@ -130,13 +179,15 @@
<pre>{{ formatText(currentLevel.techOutput) }}</pre>
</div>
</div>
<div v-else class="terminal-placeholder">
<div
v-else
class="terminal-placeholder"
>
<span>Waiting for command...</span>
</div>
</transition>
</div>
</div>
</div>
</template>
@@ -19,17 +19,17 @@
<button
v-for="s in scenarios"
:key="s.id"
@click="selectScenario(s)"
class="tab-btn"
:class="{ active: currentScenario.id === s.id }"
:disabled="isAnimating"
@click="selectScenario(s)"
>
{{ s.name }}
</button>
</div>
<div class="actions">
<button
<button
class="action-btn primary"
@click="toggleAutoPlay"
>
@@ -56,16 +56,23 @@
<!-- 传输通道 -->
<div class="channel">
<div class="channel-bg"></div>
<div class="channel-bg" />
<!-- 请求包 -->
<div class="packet request" :class="{ moving: step === 1, done: step > 1 }">
<div
class="packet request"
:class="{ moving: step === 1, done: step > 1 }"
>
<span class="packet-icon">📤</span>
<span class="packet-label">GET</span>
</div>
<!-- 响应包 -->
<div class="packet response" :class="{ moving: step === 2, done: step > 2 }" v-if="step >= 2">
<div
v-if="step >= 2"
class="packet response"
:class="{ moving: step === 2, done: step > 2 }"
>
<span class="packet-icon">📦</span>
<span class="packet-label">{{ currentScenario.status }}</span>
</div>
@@ -82,35 +89,51 @@
<!-- 底部详情面板 (固定高度) -->
<div class="detail-panel">
<transition name="fade" mode="out-in">
<div v-if="step > 0" class="detail-content" :key="step">
<!-- 左侧状态徽章 -->
<div class="detail-left" :style="{ borderColor: getStatusColor() }">
<div class="status-badge" :class="currentScenario.statusType">
{{ step === 1 ? '请求中' : currentScenario.status + ' ' + currentScenario.statusText }}
</div>
</div>
<transition
name="fade"
mode="out-in"
>
<div
v-if="step > 0"
:key="step"
class="detail-content"
>
<!-- 左侧状态徽章 -->
<div
class="detail-left"
:style="{ borderColor: getStatusColor() }"
>
<div
class="status-badge"
:class="currentScenario.statusType"
>
{{ step === 1 ? '请求中' : currentScenario.status + ' ' + currentScenario.statusText }}
</div>
</div>
<div class="detail-divider"></div>
<div class="detail-divider" />
<!-- 右侧详情 -->
<div class="detail-right">
<div class="info-row">
<span class="tag life">快递员说</span>
<span class="text highlight">
{{ step === 1 ? currentScenario.requestText : currentScenario.responseText }}
</span>
</div>
<div class="info-row">
<span class="tag tech">技术报文</span>
<span class="text code">
{{ step === 1 ? `${currentScenario.method} ${currentScenario.path} HTTP/1.1` : `HTTP/1.1 ${currentScenario.status} ${currentScenario.statusText}` }}
</span>
</div>
</div>
<!-- 右侧详情 -->
<div class="detail-right">
<div class="info-row">
<span class="tag life">快递员说</span>
<span class="text highlight">
{{ step === 1 ? currentScenario.requestText : currentScenario.responseText }}
</span>
</div>
<div class="info-row">
<span class="tag tech">技术报文</span>
<span class="text code">
{{ step === 1 ? `${currentScenario.method} ${currentScenario.path} HTTP/1.1` : `HTTP/1.1 ${currentScenario.status} ${currentScenario.statusText}` }}
</span>
</div>
</div>
</div>
<div v-else class="detail-placeholder">
<div
v-else
class="detail-placeholder"
>
<span class="guide-bounce">📦</span>
<span>选择一个场景点击"演示"看看发生了什么</span>
</div>
@@ -16,11 +16,11 @@
</div>
<div class="actions">
<button
class="action-btn primary"
@click="nextStep"
<button
v-if="currentStep < 3"
class="action-btn primary"
:disabled="currentStep >= 3"
v-if="currentStep < 3"
@click="nextStep"
>
{{ currentStep === 0 ? '▶ 开始拨号' : '下一步 ➔' }}
</button>
@@ -42,7 +42,10 @@
<span class="avatar-label">客户端 ()</span>
</div>
<transition name="pop">
<div class="bubble client" v-if="currentStep >= 1">
<div
v-if="currentStep >= 1"
class="bubble client"
>
{{ getBubbleText(1) }}
</div>
</transition>
@@ -50,11 +53,20 @@
<!-- 中间连接状态线 -->
<div class="connection-line">
<div class="line-bg"></div>
<div class="signal-packet" :class="getSignalClass()">
<span class="packet-icon" v-if="currentStep > 0">{{ getSignalIcon() }}</span>
<div class="line-bg" />
<div
class="signal-packet"
:class="getSignalClass()"
>
<span
v-if="currentStep > 0"
class="packet-icon"
>{{ getSignalIcon() }}</span>
</div>
<div class="status-badge" :class="{ connected: currentStep === 3 }">
<div
class="status-badge"
:class="{ connected: currentStep === 3 }"
>
{{ currentStep === 3 ? '✅ 连接建立' : '⏳ 连接中...' }}
</div>
</div>
@@ -66,7 +78,10 @@
<span class="avatar-label">服务器</span>
</div>
<transition name="pop">
<div class="bubble server" v-if="currentStep >= 2">
<div
v-if="currentStep >= 2"
class="bubble server"
>
{{ getBubbleText(2) }}
</div>
</transition>
@@ -80,83 +95,125 @@
:key="index"
class="step-dot"
:class="{ active: currentStep === index + 1, passed: currentStep > index + 1 }"
@click="goToStep(index + 1)"
:title="step.techTitle"
@click="goToStep(index + 1)"
>
<span class="dot-num">{{ index + 1 }}</span>
<span class="dot-line" v-if="index < steps.length - 1"></span>
<span
v-if="index < steps.length - 1"
class="dot-line"
/>
</div>
</div>
<!-- 底部详情面板 (固定高度) -->
<div class="detail-panel">
<transition name="fade" mode="out-in">
<div v-if="currentStep > 0" class="detail-content" :key="currentStep">
<div class="detail-left" :style="{ borderColor: getCurrentStepColor() }">
<div class="step-badge" :style="{ background: getCurrentStepColor() }">
步骤 {{ currentStep }}
</div>
</div>
<transition
name="fade"
mode="out-in"
>
<div
v-if="currentStep > 0"
:key="currentStep"
class="detail-content"
>
<div
class="detail-left"
:style="{ borderColor: getCurrentStepColor() }"
>
<div
class="step-badge"
:style="{ background: getCurrentStepColor() }"
>
步骤 {{ currentStep }}
</div>
</div>
<div class="detail-divider"></div>
<div class="detail-divider" />
<div class="detail-right">
<div class="info-row">
<span class="tag life">生活对话</span>
<span class="text highlight">{{ steps[currentStep-1].simpleTitle }}</span>
</div>
<div class="info-row">
<span class="tag tech">技术原理</span>
<div class="tech-content">
<div class="tech-desc">{{ steps[currentStep-1].techDesc }}</div>
<!-- 动态名词解码卡片 -->
<div class="term-glossary">
<div v-for="term in steps[currentStep-1].terms" :key="term.key" class="term-item">
<span class="term-key">{{ term.key }}</span>
<span class="term-val">{{ term.val }}</span>
</div>
</div>
<div class="detail-right">
<div class="info-row">
<span class="tag life">生活对话</span>
<span class="text highlight">{{ steps[currentStep-1].simpleTitle }}</span>
</div>
<div class="info-row">
<span class="tag tech">技术原理</span>
<div class="tech-content">
<div class="tech-desc">
{{ steps[currentStep-1].techDesc }}
</div>
<!-- 动态名词解码卡片 -->
<div class="term-glossary">
<div
v-for="term in steps[currentStep-1].terms"
:key="term.key"
class="term-item"
>
<span class="term-key">{{ term.key }}</span>
<span class="term-val">{{ term.val }}</span>
</div>
</div>
<!-- 代码实现细节 (折叠) -->
<details class="code-details" v-if="steps[currentStep-1].codeImpl">
<summary class="code-summary">
<span class="summary-icon">🛠</span>
<span class="summary-text">技术深究底层代码如何实现</span>
</summary>
<div class="code-block-wrapper">
<div class="code-title">{{ steps[currentStep-1].codeImpl.title }}</div>
<pre class="code-block"><code v-html="steps[currentStep-1].codeImpl.code"></code></pre>
<!-- 代码实现细节 (折叠) -->
<details
v-if="steps[currentStep-1].codeImpl"
class="code-details"
>
<summary class="code-summary">
<span class="summary-icon">🛠</span>
<span class="summary-text">技术深究底层代码如何实现</span>
</summary>
<div class="code-block-wrapper">
<div class="code-title">
{{ steps[currentStep-1].codeImpl.title }}
</div>
<pre class="code-block"><code v-html="steps[currentStep-1].codeImpl.code" /></pre>
</div>
</details>
<!-- 技术问答 (折叠) - 仅在有问答时显示 -->
<details class="code-details qa-details" v-if="steps[currentStep-1].qa">
<details
v-if="steps[currentStep-1].qa"
class="code-details qa-details"
>
<summary class="code-summary qa-summary">
<span class="summary-icon">🎓</span>
<span class="summary-text">{{ steps[currentStep-1].qa.title }}</span>
</summary>
<div class="code-block-wrapper qa-content">
<div v-for="(item, idx) in steps[currentStep-1].qa.content" :key="idx" class="qa-item">
<div class="qa-q">Q: {{ item.q }}</div>
<div class="qa-a" v-html="item.a"></div>
<div
v-for="(item, idx) in steps[currentStep-1].qa.content"
:key="idx"
class="qa-item"
>
<div class="qa-q">
Q: {{ item.q }}
</div>
<div
class="qa-a"
v-html="item.a"
/>
</div>
</div>
</details>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 下一步按钮 -->
<button
class="next-btn"
v-if="currentStep < 3"
@click="nextStep"
>
下一步
</button>
<!-- 下一步按钮 -->
<button
v-if="currentStep < 3"
class="next-btn"
@click="nextStep"
>
下一步
</button>
</div>
<div v-else class="detail-placeholder">
<div
v-else
class="detail-placeholder"
>
<span class="guide-bounce">📞</span>
<span>点击"开始拨号"或步骤圆点开始拨打电话</span>
</div>
@@ -11,7 +11,10 @@
<div class="url-parser-order">
<!-- 顶部输入区 -->
<div class="input-section">
<div class="url-input-box" :class="{ 'has-error': error }">
<div
class="url-input-box"
:class="{ 'has-error': error }"
>
<span class="input-label">URL</span>
<input
v-model="urlInput"
@@ -19,17 +22,23 @@
placeholder="https://www.example.com/path?query=1"
class="real-input"
@input="parseUrl"
/>
<button v-if="urlInput" class="clear-btn" @click="clear"></button>
>
<button
v-if="urlInput"
class="clear-btn"
@click="clear"
>
</button>
</div>
<div class="quick-actions">
<span class="action-label">试一试</span>
<button
v-for="ex in examples"
:key="ex.name"
@click="useExample(ex)"
class="action-chip"
:class="{ active: currentExample === ex.name }"
@click="useExample(ex)"
>
{{ ex.name }}
</button>
@@ -48,8 +57,8 @@
<div class="code-blocks">
<div
v-for="(field, key) in formFields"
:key="key"
v-show="shouldShowField(key)"
:key="key"
class="code-block"
:class="[key, { active: hovered === key }]"
:style="{ '--color': field.color }"
@@ -75,19 +84,24 @@
<span class="title">购物订单</span>
</div>
<div class="order-ticket">
<div class="ticket-hole"></div>
<div class="ticket-hole" />
<div
v-for="(field, key) in formFields"
:key="key"
v-show="shouldShowField(key)"
:key="key"
class="ticket-row"
:class="{ active: hovered === key }"
:style="{ '--color': field.color }"
@mouseenter="hovered = key"
@mouseleave="hovered = null"
>
<div class="ticket-icon" :style="{ backgroundColor: field.color }">{{ field.icon }}</div>
<div
class="ticket-icon"
:style="{ backgroundColor: field.color }"
>
{{ field.icon }}
</div>
<div class="ticket-content">
<span class="ticket-label">{{ field.analogyLabel }}</span>
<span class="ticket-desc">{{ field.analogyDesc }}</span>
@@ -99,24 +113,45 @@
<!-- 技术答疑面板 -->
<transition name="fade">
<div class="qa-panel" v-if="activeQa">
<div class="qa-header">{{ activeQa.title }}</div>
<div
v-if="activeQa"
class="qa-panel"
>
<div class="qa-header">
{{ activeQa.title }}
</div>
<div class="qa-content">
<div v-for="(item, idx) in activeQa.content" :key="idx" class="qa-item">
<div class="qa-q">Q: {{ item.q }}</div>
<div class="qa-a">A: {{ item.a }}</div>
<div
v-for="(item, idx) in activeQa.content"
:key="idx"
class="qa-item"
>
<div class="qa-q">
Q: {{ item.q }}
</div>
<div class="qa-a">
A: {{ item.a }}
</div>
</div>
</div>
</div>
<div class="qa-placeholder" v-else>
<div
v-else
class="qa-placeholder"
>
👆 鼠标悬停在上方色块查看详细技术解释
</div>
</transition>
</template>
<!-- 空状态引导 -->
<div class="empty-state" v-else>
<div class="empty-icon">🛒</div>
<div
v-else
class="empty-state"
>
<div class="empty-icon">
🛒
</div>
<div class="empty-text">
<p>输入网址生成你的"数字购物单"</p>
<span class="sub-text">看看浏览器如何理解这一长串字符</span>
@@ -11,52 +11,66 @@
<template>
<div class="quick-start-compact">
<!-- 顶部极简输入栏 -->
<div class="input-bar" :class="{ 'is-active': isActive }">
<div
class="input-bar"
:class="{ 'is-active': isActive }"
>
<div class="input-wrapper">
<span class="protocol">https://</span>
<input
v-model="url"
type="text"
placeholder="输入网址,开始旅程..."
@keyup.enter="handleMainAction"
:disabled="isActive && !isFinished"
/>
@keyup.enter="handleMainAction"
>
<!-- 主操作按钮 -->
<button
class="start-btn"
:class="{ 'next-btn': isActive && !isFinished, 'reset-btn': isFinished }"
@click="handleMainAction"
:disabled="!url"
:disabled="!url"
@click="handleMainAction"
>
{{ mainButtonText }}
</button>
</div>
<!-- 步骤控制按钮组 -->
<div class="step-controls" v-if="isActive">
<div
v-if="isActive"
class="step-controls"
>
<button
class="control-btn"
@click="prevStep"
:disabled="currentStep === 0"
:disabled="currentStep === 0"
title="上一步"
@click="prevStep"
>
</button>
<button
class="control-btn"
@click="nextStep"
:disabled="isFinished"
:disabled="isFinished"
title="下一步"
@click="nextStep"
>
</button>
</div>
<!-- 快速体验按钮 (仅在未开始时显示) -->
<div class="quick-chips" v-if="!isActive">
<div
v-if="!isActive"
class="quick-chips"
>
<span class="chip-label">试一试:</span>
<button v-for="u in quickUrls" :key="u" @click="quickStart(u)" class="chip">
<button
v-for="u in quickUrls"
:key="u"
class="chip"
@click="quickStart(u)"
>
{{ u }}
</button>
</div>
@@ -66,7 +80,10 @@
<div class="conveyor-stage">
<!-- 进度轨道 -->
<div class="track-line">
<div class="track-progress" :style="{ width: packagePosition + '%' }"></div>
<div
class="track-progress"
:style="{ width: packagePosition + '%' }"
/>
</div>
<!-- 站点节点 -->
@@ -83,19 +100,23 @@
>
<div class="station-icon-box">
<span class="station-icon">{{ step.icon }}</span>
<div class="station-status-dot"></div>
<div class="station-status-dot" />
</div>
<div class="station-label">
{{ step.name }}
</div>
<div class="station-label">{{ step.name }}</div>
</div>
<!-- 移动的包裹 (绝对定位) -->
<div
v-show="isActive"
class="moving-package"
:style="{ '--package-pos': packagePosition }"
v-show="isActive"
>
<div class="package-body">📦</div>
<div class="package-shadow"></div>
<div class="package-body">
📦
</div>
<div class="package-shadow" />
<!-- 动态提示气泡 -->
<div class="package-bubble">
<span class="bubble-analogy">{{ steps[currentStep]?.analogyAction }}</span>
@@ -105,26 +126,38 @@
<!-- 底部动态对照条 -->
<div class="dynamic-info-bar">
<transition name="slide-up" mode="out-in">
<div v-if="isActive" :key="currentStep" class="info-content">
<transition
name="slide-up"
mode="out-in"
>
<div
v-if="isActive"
:key="currentStep"
class="info-content"
>
<div class="info-left">
<span class="stage-badge"> {{ currentStep + 1 }} </span>
<span class="stage-title">{{ steps[currentStep].title }}</span>
</div>
<div class="info-divider"></div>
<div class="info-divider" />
<div class="info-right">
<div class="mapping-item">
<span class="mapping-icon">🚚</span>
<span class="mapping-text">生活{{ steps[currentStep].analogyDesc }}</span>
</div>
<div class="mapping-arrow"></div>
<div class="mapping-arrow">
</div>
<div class="mapping-item">
<span class="mapping-icon">💻</span>
<span class="mapping-text">技术{{ steps[currentStep].techDesc }}</span>
</div>
</div>
</div>
<div v-else class="info-placeholder">
<div
v-else
class="info-placeholder"
>
👈 在左上角输入网址开启网络快递之旅
</div>
</transition>