kindergarten_java/docs/design/24-展播模式优化设计.md
Claude Opus 4.6 7e625f31e3 fix: 修复前端路由配置和响应拦截器问题
- 修复路由配置:移除 top-level await,改用手动路由配置
- 修复响应拦截器:正确解包 { code, message, data } 格式的 API 响应
- 更新开发日志和变更日志,记录浏览器功能测试结果
- 添加教师端重构设计文档

修复的问题:
1. 登录功能无法正常工作(响应数据解包问题)
2. 页面无法加载(路由配置问题)

测试结果:
- 管理员登录: ✓ 成功
- 教师登录: ✓ 成功
- 主要页面导航: ✓ 正常

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 14:09:56 +08:00

1206 lines
37 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 展播模式优化设计文档
> **文档版本:** v1.0
> **创建日期:** 2026-03-11
> **目标:** 将授课内容以儿童友好的方式展示,方便儿童直接观看
---
## 📋 目录
1. [设计目标](#1-设计目标)
2. [视觉风格设计](#2-视觉风格设计)
3. [资源陈列优化](#3-资源陈列优化)
4. [播放体验设计](#4-播放体验设计)
5. [互动元素设计](#5-互动元素设计)
6. [导航控制设计](#6-导航控制设计)
7. [响应式设计](#7-响应式设计)
8. [技术实现](#8-技术实现)
9. [设计规范](#9-设计规范)
---
## 1. 设计目标
### 1.1 核心目标
| 目标 | 说明 |
|------|------|
| **儿童友好** | 界面色彩活泼、操作简单、视觉清晰 |
| **资源陈列** | 三类课程的数字资源美观展示、易于选择 |
| **播放体验** | 资源播放流畅、控制方便、观赏舒适 |
| **互动趣味** | 加入动画、音效、奖励机制,增强参与感 |
### 1.2 使用场景
| 场景 | 设备 | 观看距离 | 特点 |
|------|------|----------|------|
| 课堂投屏 | 智能屏/投影仪 | 2-5米 | 大屏显示、多人观看 |
| 一对一教学 | 平板 | 0.5-1米 | 触摸操作、近距离观看 |
| 家庭学习 | TV/平板 | 1-3米 | 家庭环境、家长陪同 |
### 1.3 用户特点
- **年龄范围**3-6岁幼儿
- **认知特点**:视觉主导、注意力易分散、喜爱动画和鲜艳色彩
- **操作能力**:大动作协调,精细动作发展中
---
## 2. 视觉风格设计
### 2.1 配色方案
```
┌─────────────────────────────────────────────────────────────┐
│ 主色系统 │
├─────────────────────────────────────────────────────────────┤
│ 主色:温暖橙 #FF8C42 (RGB: 255, 140, 66) │
│ 辅助色: │
│ - 天空蓝 #74B9FF (RGB: 116, 185, 255) │
│ - 薄荷绿 #00D9A5 (RGB: 0, 217, 165) │
│ - 珊瑚粉 #FF7675 (RGB: 255, 118, 117) │
│ - 柠檬黄 #FFD93D (RGB: 255, 217, 61) │
│ │
│ 中性色: │
│ - 背景浅 #FFF9F0 (RGB: 255, 249, 240) │
│ - 背景深 #FFF4E6 (RGB: 255, 244, 230) │
│ - 文字主 #2D3436 (RGB: 45, 52, 54) │
│ - 文字辅 #636E72 (RGB: 99, 110, 114) │
│ │
│ 功能色: │
│ - 成功 #52C41A (RGB: 82, 196, 26) │
│ - 警告 #FFA940 (RGB: 255, 169, 64) │
│ - 错误 #FF4D4F (RGB: 255, 77, 79) │
└─────────────────────────────────────────────────────────────┘
```
### 2.2 背景设计
#### 2.2.1 渐变背景
```
主背景:从顶部到底部的柔和渐变
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
顶部:#FFE8D6 (温暖桃色)
中部:#FFF9F0 (奶油色)
底部:#F0F9FF (淡蓝色)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
```
#### 2.2.2 装饰元素
**选项A云朵装饰**
```
位置:顶部和底部随机分布
大小80-120px
透明度60%
动画缓慢飘动20秒循环
```
**选项B星星装饰**
```
位置:背景随机分布
大小20-40px
颜色:柠檬黄 #FFD93D
动画闪烁效果3秒循环
```
**选项C几何图形**
```
元素:圆形、三角形、正方形
颜色:辅助色(半透明)
分布:背景点缀
动画:缓慢旋转
```
### 2.3 字体设计
| 用途 | 字号 | 字重 | 行高 | 说明 |
|------|------|------|------|------|
| 主标题 | 32-40px | 600 | 1.2 | 课程/环节名称 |
| 正文 | 18-22px | 400 | 1.5 | 内容说明 |
| 按钮 | 16-18px | 500 | - | 操作按钮 |
### 2.4 圆角设计
```scss
// 统一圆角规范
$radius-sm: 12px; // 小卡片、按钮
$radius-md: 16px; // 中等卡片
$radius-lg: 24px; // 大卡片
$radius-xl: 32px; // 容器
```
---
## 3. 资源陈列优化
### 3.1 整体布局结构
```
┌──────────────────────────────────────────────────────────────────┐
│ 展播模式主界面 │
├──────────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ 主内容区 │ │
│ │ ┌─────────────────────────────────────────────────────┐ │ │
│ │ │ │ │ │
│ │ │ 资源播放区(大屏显示) │ │ │
│ │ │ │ │ │
│ │ │ │ │ │
│ │ └─────────────────────────────────────────────────────┘ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ 底部导航栏 │ │
│ │ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │ │
│ │ │ 环节 │ │ 资源 │ │ 进度 │ │ 延伸 │ │ │
│ │ │ 导航 │ │ 快速 │ │ 显示 │ │ 活动 │ │ │
│ │ └────────┘ └────────┘ └────────┘ └────────┘ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────┘
```
### 3.2 课程级资源展示区
**位置:** 主内容区顶部(自动收起)
```vue
<!-- 课程资源横幅 -->
<div class="course-resources-banner" v-if="showCourseResources">
<div class="resource-cards">
<!-- 视频资源 -->
<div v-if="courseVideos.length" class="resource-card video-card">
<div class="card-icon">🎬</div>
<div class="card-info">
<span class="card-title">课程视频</span>
<span class="card-count">{{ courseVideos.length }}个</span>
</div>
<button class="play-btn" @click="playCourseVideo">
<PlayIcon /> 播放
</button>
</div>
<!-- PPT资源 -->
<div v-if="coursePpts.length" class="resource-card ppt-card">
<div class="card-icon">📊</div>
<div class="card-info">
<span class="card-title">教学课件</span>
<span class="card-count">{{ coursePpts.length }}个</span>
</div>
<button class="play-btn" @click="showCoursePpts">
<ViewIcon /> 预览
</button>
</div>
<!-- 文档资源 -->
<div v-if="courseDocs.length" class="resource-card doc-card">
<div class="card-icon">📄</div>
<div class="card-info">
<span class="card-title">教学文档</span>
<span class="card-count">{{ courseDocs.length }}个</span>
</div>
<button class="play-btn" @click="showCourseDocs">
<ReadIcon /> 查看
</button>
</div>
</div>
</div>
```
**样式规范:**
```scss
.course-resources-banner {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 100;
padding: 16px 24px;
background: linear-gradient(180deg, #FFF9F0 0%, rgba(255, 249, 240, 0) 100%);
display: flex;
justify-content: center;
animation: slideDown 0.3s ease;
.resource-cards {
display: flex;
gap: 16px;
}
.resource-card {
display: flex;
align-items: center;
gap: 12px;
padding: 16px 24px;
background: white;
border-radius: 24px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
.card-icon {
width: 48px;
height: 48px;
display: flex;
align-items: center;
justify-content: center;
font-size: 28px;
background: #FFF4E6;
border-radius: 12px;
}
.play-btn {
padding: 10px 20px;
border-radius: 20px;
background: linear-gradient(135deg, #FF8C42, #E67635);
color: white;
font-size: 16px;
font-weight: 500;
border: none;
cursor: pointer;
transition: transform 0.2s;
&:hover {
transform: scale(1.05);
}
}
}
}
```
### 3.3 环节资源卡片
**设计:** 横向滚动的卡片式布局
```
┌────────────────────────────────────────────────────────────┐
│ 教学环节 │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ 1⃣ 导入 │ │ 2⃣ 共读 │ │ 3⃣ 讨论 │ │ 4⃣ 活动 │ │
│ │ │ │ │ │ │ │ │ │
│ │ [资源] │ │ [资源] │ │ [资源] │ │ [资源] │ │
│ │ [资源] │ │ [资源] │ │ │ │ [资源] │ │
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
│ ⭐ ⭐ ⭐ ⬜ │
└────────────────────────────────────────────────────────────┘
```
**实现规范:**
```vue
<!-- 环节资源卡片 -->
<div class="step-resources-section">
<div class="section-title">
<span class="title-text">教学环节</span>
<span class="title-badge">{{ currentStepIndex + 1 }}/{{ steps.length }}</span>
</div>
<div class="step-cards-container">
<div
v-for="(step, index) in steps"
:key="step.id"
class="step-card"
:class="{
active: currentStepIndex === index,
completed: index < currentStepIndex
}"
@click="selectStep(index)"
>
<!-- 环节头部 -->
<div class="step-header">
<div class="step-number">{{ index + 1 }}</div>
<div class="step-info">
<div class="step-name">{{ step.name }}</div>
<div class="step-duration">{{ step.duration }}分钟</div>
</div>
<div class="step-status">
<StarIcon v-if="index < currentStepIndex" class="completed-star" />
</div>
</div>
<!-- 环节资源 -->
<div class="step-resources">
<!-- 图片资源 -->
<div
v-for="(img, idx) in step.images.slice(0, 2)"
:key="`img-${idx}`"
class="resource-thumb image-thumb"
@click.stop="showResource('image', img)"
>
<img :src="getResourceUrl(img.path)" :alt="img.name" />
</div>
<!-- 视频资源 -->
<div
v-if="step.videos.length > 0"
class="resource-thumb video-thumb"
@click.stop="showResource('video', step.videos[0])"
>
<div class="thumb-icon">🎬</div>
<span class="thumb-label">视频</span>
</div>
<!-- 音频资源 -->
<div
v-if="step.audioList.length > 0"
class="resource-thumb audio-thumb"
@click.stop="showResource('audio', step.audioList[0])"
>
<div class="thumb-icon">🎵</div>
<span class="thumb-label">音频</span>
</div>
<!-- 更多资源提示 -->
<div
v-if="getStepResourceCount(step) > 3"
class="resource-thumb more-thumb"
@click.stop="showResourceList(step)"
>
<div class="thumb-icon"></div>
<span class="thumb-label">{{ getStepResourceCount(step) - 2 }}+</span>
</div>
</div>
</div>
</div>
</div>
```
**样式规范:**
```scss
.step-cards-container {
display: flex;
gap: 20px;
overflow-x: auto;
padding: 8px 4px;
scroll-snap-type: x mandatory;
&::-webkit-scrollbar {
height: 8px;
}
&::-webkit-scrollbar-track {
background: rgba(0, 0, 0, 0.05);
border-radius: 4px;
}
&::-webkit-scrollbar-thumb {
background: rgba(255, 140, 66, 0.3);
border-radius: 4px;
&:hover {
background: rgba(255, 140, 66, 0.5);
}
}
}
.step-card {
flex: 0 0 280px;
scroll-snap-align: start;
background: white;
border-radius: 20px;
padding: 16px;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
cursor: pointer;
transition: all 0.3s ease;
border: 3px solid transparent;
&:hover {
transform: translateY(-4px);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
}
&.active {
border-color: #FF8C42;
background: linear-gradient(135deg, #FFF9F0 0%, #FFF4E6 100%);
}
&.completed {
opacity: 0.7;
.completed-star {
color: #FFD93D;
font-size: 24px;
animation: starPop 0.5s ease;
}
}
.step-header {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 12px;
.step-number {
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, #FF8C42, #E67635);
color: white;
border-radius: 12px;
font-size: 18px;
font-weight: 600;
}
.step-info {
flex: 1;
.step-name {
font-size: 18px;
font-weight: 600;
color: #2D3436;
margin-bottom: 2px;
}
.step-duration {
font-size: 13px;
color: #636E72;
}
}
}
.step-resources {
display: flex;
gap: 8px;
flex-wrap: wrap;
}
.resource-thumb {
display: flex;
flex-direction: column;
align-items: center;
gap: 4px;
padding: 8px 12px;
border-radius: 12px;
background: #F8F8F8;
cursor: pointer;
transition: all 0.2s;
&:hover {
background: #FFE8D6;
transform: scale(1.05);
}
.thumb-icon {
font-size: 24px;
}
.thumb-label {
font-size: 11px;
color: #636E72;
}
&.image-thumb {
img {
width: 60px;
height: 60px;
object-fit: cover;
border-radius: 8px;
}
}
}
}
```
---
## 4. 播放体验设计
### 4.1 主内容区布局
```
┌──────────────────────────────────────────────────────────────┐
│ │
│ ┌─────────────────┐ │
│ │ │ │
│ │ 资源播放区 │ │
│ │ │ │
│ │ (视频/绘本) │ │
│ │ │ │
│ │ │ │
│ └─────────────────┘ │
│ │
│ ← [ 1/5 ] → │
│ │
└──────────────────────────────────────────────────────────────┘
```
### 4.2 视频播放器设计
**自定义播放器控件:**
```
┌──────────────────────────────────────────────────────────────┐
│ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 视频内容 │ │
│ │ │ │
│ └───────────────────────────────────────────────────────┘ │
│ │
│ ┌──────┐ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ┌──────┐ │
│ │ ⏮ │ ◐━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │ ⏸ │ │
│ └──────┘ 00:00 / 05:32 └──────┘ │
│ │
│ [ 🔊 ] [ 🔍 ] [ ⛶ ] [ 📺 ] [ ⚙️ ] │
│ │
└──────────────────────────────────────────────────────────────┘
```
**按钮尺寸规范:**
- 播放/暂停64x64px
- 音量48x48px
- 全屏48x48px
- 其他40x40px
### 4.3 绘本阅读器设计
**翻页效果:**
```vue
<EbookViewer>
<!-- 当前页面 -->
<div class="ebook-page" :style="{ transform: pageTransform }">
<img :src="currentPage.url" :alt="currentPage.name" />
</div>
<!-- 翻页控件 -->
<div class="ebook-controls">
<button class="nav-btn prev" @click="prevPage">
<ChevronLeft :size="48" />
</button>
<!-- 页面指示器 -->
<div class="page-indicator">
<div
v-for="(page, index) in pages"
:key="index"
class="page-dot"
:class="{ active: currentPageIndex === index }"
></div>
</div>
<button class="nav-btn next" @click="nextPage">
<ChevronRight :size="48" />
</button>
</div>
<!-- 缩略图条带 -->
<div class="thumbnail-strip">
<div
v-for="(page, index) in pages"
:key="index"
class="thumbnail"
:class="{ active: currentPageIndex === index }"
@click="jumpToPage(index)"
>
<img :src="page.thumbnail" />
<span class="page-num">{{ index + 1 }}</span>
</div>
</div>
</EbookViewer>
```
**翻页动画:**
```scss
@keyframes pageTurn {
0% {
transform: rotateY(0deg);
opacity: 1;
}
50% {
transform: rotateY(-90deg);
opacity: 0.5;
}
100% {
transform: rotateY(0deg);
opacity: 1;
}
}
.ebook-page {
animation: pageTurn 0.6s ease-in-out;
transform-style: preserve-3d;
}
```
### 4.4 PPT/挂图查看器设计
**布局:**
```
┌──────────────────────────────────────────────────────────────┐
│ [X] 教学课件 - PPT1 │
│ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ PPT 页面 │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ └───────────────────────────────────────────────────────┘ │
│ │
│ ┌─────┐ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ┌─────┐ │
│ │ ◀│ ●────────●────────────────────● │ ▶ │ │
│ └─────┘ 1 / 15 └─────┘ │
│ │
│ [ 🔍 ] [ ⛶ ] [ 📤 ] │
└──────────────────────────────────────────────────────────────┘
```
**缩略图条带:**
```vue
<div class="slides-viewer">
<!-- 缩略图条带 -->
<div class="thumbnail-strip">
<div
v-for="(slide, index) in slides"
:key="index"
class="slide-thumbnail"
:class="{ active: currentSlide === index }"
@click="goToSlide(index)"
>
<img :src="slide.thumbnail" />
</div>
</div>
</div>
```
---
## 5. 互动元素设计
### 5.1 音效系统
**音效清单:**
| 交互 | 音效 | 音量 | 说明 |
|------|------|------|------|
| 环节切换 | 轻柔"嗖"声 | 50% | 过渡提示 |
| 资源点击 | "波"音 | 40% | 点击反馈 |
| 完成环节 | 鼓掌声 | 60% | 正向强化 |
| 全部完成 | 欢呼声 + 钟声 | 70% | 庆祝 |
| 错误操作 | 轻柔"唔"声 | 30% | 提示纠正 |
**实现方式:**
```typescript
// 音效管理类
class SoundEffectManager {
private audioContext: AudioContext;
playSound(soundName: string) {
const sounds = {
'stepChange': '/assets/sounds/whoosh.mp3',
'click': '/assets/sounds/bloop.mp3',
'complete': '/assets/sounds/applause.mp3',
'celebrate': '/assets/sounds/celebrate.mp3',
'error': '/assets/sounds/hmm.mp3',
};
const audio = new Audio(sounds[soundName]);
audio.volume = this.getVolume(soundName);
audio.play().catch(err => console.log('Sound play error:', err));
}
private getVolume(soundName: string): number {
const volumes = {
'stepChange': 0.5,
'click': 0.4,
'complete': 0.6,
'celebrate': 0.7,
'error': 0.3,
};
return volumes[soundName] || 0.5;
}
}
```
### 5.2 动画效果
**环节切换动画:**
```scss
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.fade-enter-active {
animation: fadeInUp 0.4s ease-out;
}
```
**资源卡片动画:**
```scss
@keyframes popIn {
0% {
transform: scale(0.8);
opacity: 0;
}
50% {
transform: scale(1.05);
}
100% {
transform: scale(1);
opacity: 1;
}
}
.resource-card {
animation: popIn 0.3s ease-out;
}
```
**星星收集动画:**
```scss
@keyframes starCollect {
0% {
transform: scale(0) rotate(0deg);
opacity: 0;
}
50% {
transform: scale(1.3) rotate(180deg);
}
100% {
transform: scale(1) rotate(360deg);
opacity: 1;
}
}
.star-animation {
animation: starCollect 0.6s ease-out;
}
```
**庆祝动画:**
```scss
@keyframes confetti {
0% {
transform: translateY(-100%) rotate(0deg);
opacity: 1;
}
100% {
transform: translateY(100vh) rotate(720deg);
opacity: 0;
}
}
.confetti-piece {
position: fixed;
width: 10px;
height: 10px;
animation: confetti 3s ease-out forwards;
}
```
### 5.3 奖励机制
**星星收集系统:**
```
完成环节 → 收集星星 → 全部完成 → 庆祝动画
┌──────────────────────────────────────────────────────────────┐
│ ★ ★ ★ ★ ★ │
│ 已完成 4 个环节,继续加油! │
└──────────────────────────────────────────────────────────────┘
```
**等级徽章:**
- 3颗星铜牌学员 🥉
- 5颗星银牌学员 🥈
- 7颗星金牌学员 🥇
- 全部完成:超级小英雄 🦸‍♂️
**庆祝画面:**
```
┌──────────────────────────────────────────────────────────────┐
│ │
│ 🎉 太棒了!🎉 │
│ │
│ 你完成了所有教学环节! │
│ │
│ 🏆 超级小英雄 🏆 │
│ │
│ [ 再来一次 ] [ 返回首页 ] │
│ │
└──────────────────────────────────────────────────────────────┘
```
---
## 6. 导航控制设计
### 6.1 底部导航栏设计
**完整布局:**
```
┌──────────────────────────────────────────────────────────────┐
│ 🎯 教学环节 │
│ ┌────┐ ┌────┐ ┌────┐ ┌────┐ │
│ │ 1⃣ │ │ 2⃣ │ │ 3⃣ │ │ 4⃣ │ ... │
│ │导入│ │共读│ │讨论│ │活动│ │
│ └────┘ └────┘ └────┘ └────┘ │
│ ⭐ ⭐ ⭐ ⬜ │
│ │
│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │ │
│ 1/4 环节 │ │
│ 05:32 │ │
│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │ │
│ │
│ 🎨 延伸活动 (可选) │
│ ┌──────┐ ┌──────┐ ┌──────┐ │
│ │ 🎨 │ │ 🎮 │ │ 🎵 │ │
│ │美工│ │游戏│ │音乐│ │
│ └──────┘ └──────┘ └──────┘ │
│ │
│ [ ◀️ 上一环节 ] [ ▶️ 下一环节 ] [ ❌ 退出展播 ] │
│ │
└──────────────────────────────────────────────────────────────┘
```
### 6.2 控制按钮规范
```scss
.ctrl-btn {
display: flex;
align-items: center;
gap: 8px;
padding: 14px 28px;
border-radius: 28px;
background: rgba(255, 255, 255, 0.9);
border: 2px solid rgba(0, 0, 0, 0.1);
color: #2D3436;
font-size: 16px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
&:hover:not(:disabled) {
background: white;
transform: translateY(-2px);
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12);
}
&:active:not(:disabled) {
transform: translateY(0);
}
&:disabled {
opacity: 0.4;
cursor: not-allowed;
}
// 主要按钮(下一环节)
&.primary {
background: linear-gradient(135deg, #FF8C42, #E67635);
border: none;
color: white;
font-size: 18px;
padding: 14px 32px;
box-shadow: 0 6px 20px rgba(255, 140, 66, 0.3);
&:hover:not(:disabled) {
background: linear-gradient(135deg, #FF7A2A, #E67635);
transform: translateY(-2px);
box-shadow: 0 8px 24px rgba(255, 140, 66, 0.4);
}
}
// 退出按钮
&.exit {
background: rgba(255, 77, 79, 0.1);
border-color: rgba(255, 77, 79, 0.3);
color: #ff4d4f;
&:hover {
background: rgba(255, 77, 79, 0.2);
}
}
}
```
### 6.3 快捷键设计
| 快捷键 | 功能 | 说明 |
|--------|------|------|
| ← / A | 上一环节 | 方便左右手操作 |
| → / D | 下一环节 | 方便左右手操作 |
| 空格 | 暂停/播放 | 大按钮,易操作 |
| ESC | 退出展播 | 紧急退出 |
| F11 | 全屏切换 | 沉浸式体验 |
| ↑ / ↓ | 音量调节 | 便于控制 |
---
## 7. 响应式设计
### 7.1 屏幕适配
```
┌─────────────────────────────────────────────────────────────┐
│ 屏幕类型 | 比例 | 设计重点 │
├─────────────────────────────────────────────────────────────┤
│ 智能屏/投影仪 | 16:9 | 大屏显示、多人观看 │
│ 传统投影仪 | 4:3 | 居中显示、边缘裁剪 │
│ 平板横屏 | 16:9 | 触摸优化、手势支持 │
│ 平板竖屏 | 9:16 | 调整布局、上下滚动 │
└─────────────────────────────────────────────────────────────┘
```
### 7.2 断点规范
```scss
// 响应式断点
$breakpoint-sm: 768px; // 平板
$breakpoint-md: 1024px; // 小桌面
$breakpoint-lg: 1280px; // 桌面
$breakpoint-xl: 1536px; // 大屏
// 响应式 mixins
@mixin respond-to($breakpoint) {
@media (min-width: $breakpoint) {
@content;
}
}
// 针对不同屏幕尺寸调整
.broadcast-view {
@include respond-to($breakpoint-lg) {
// 大屏:显示完整资源
.resource-card {
flex: 0 0 280px;
}
}
@include respond-to($breakpoint-md) {
// 中屏:缩小资源卡片
.resource-card {
flex: 0 0 240px;
}
}
@include respond-to($breakpoint-sm) {
// 小屏:横向滚动
.resource-card {
flex: 0 0 200px;
}
}
}
```
### 7.3 字体缩放
```scss
// 根据屏幕尺寸调整字体
html {
font-size: 16px;
@media (max-width: 768px) {
font-size: 14px;
}
@media (min-width: 1536px) {
font-size: 18px;
}
}
```
---
## 8. 技术实现
### 8.1 组件结构
```
BroadcastView.vue (展播入口)
├─ KidsMode.vue (儿童友好界面)
│ ├─ EbookViewer.vue (绘本阅读器)
│ ├─ VideoPlayer.vue (视频播放器)
│ ├─ AudioPlayer.vue (音频播放器)
│ └─ SlidesViewer.vue (PPT/挂图查看器)
```
### 8.2 状态管理
```typescript
interface BroadcastState {
// 课程数据
course: Course | null;
lessons: Lesson[];
activities: Activity[];
// 当前位置
currentLessonIndex: number;
currentStepIndex: number;
// 资源状态
currentResourceType: 'ebook' | 'video' | 'audio' | 'ppt' | 'poster' | '';
currentResourceUrl: string;
showingResource: Resource | null;
// UI状态
controlsVisible: boolean;
activityModalVisible: boolean;
// 进度
progressPercent: number;
timerSeconds: number;
}
```
### 8.3 资源处理
**资源URL处理**
```typescript
const getFileUrl = (filePath: string): string => {
if (!filePath) return '';
if (filePath.startsWith('http://') || filePath.startsWith('https://')) {
return filePath;
}
const SERVER_BASE = import.meta.env.VITE_SERVER_BASE_URL || 'http://localhost:3000';
return `${SERVER_BASE}${filePath}`;
};
```
**资源类型图标映射:**
```typescript
const resourceIconMap: Record<string, Component> = {
'image': PictureOutlined,
'video': VideoCameraOutlined,
'audio': AudioOutlined,
'ppt': FilePptOutlined,
'poster: FileImageOutlined,
'ebook': BookOutlined,
};
```
### 8.4 动画库选择
推荐使用:
- **Vue Transition** - 内置过渡动画
- **Animate.css** - CSS动画库可选
- **Lottie** - JSON动画高级
---
## 9. 设计规范
### 9.1 间距规范
```scss
$spacing-xs: 4px;
$spacing-sm: 8px;
$spacing-md: 12px;
$spacing-lg: 16px;
$spacing-xl: 20px;
$spacing-xxl: 24px;
$spacing-xxxl: 32px;
```
### 9.2 阴影规范
```scss
// 卡片阴影
$shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.06);
$shadow-md: 0 4px 16px rgba(0, 0, 0, 0.08);
$shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.12);
// 按钮阴影
$shadow-button: 0 4px 12px rgba(255, 140, 66, 0.3);
$shadow-button-hover: 0 6px 16px rgba(255, 140, 66, 0.4);
```
### 9.3 动画时长
```scss
$duration-fast: 0.2s;
$duration-normal: 0.3s;
$duration-slow: 0.5s;
$duration-slower: 0.8s;
```
### 9.4 Z-index 层级
```scss
$z-modal: 1000;
$z-dropdown: 1050;
$z-sticky: 1020;
$z-fixed: 1030;
$z-tooltip: 1060;
```
---
## 附录:三类课程特色展示
### A. 导入课
**主题图标:** 🔍 (放大镜)
**配色:** 温暖橙 #FF8C42
**特色元素:**
- 强调"认识"和"发现"
- 大图标、清晰指引
- 温馨鼓励语
### B. 集体课
**主题图标:** 📖 (打开的书)
**配色:** 天空蓝 #74B9FF
**特色元素:**
- 突出"共读"主题
- 绘本封面展示
- 互动问题提示
### C. 领域课
**配色方案:**
- 语言:📝 天空蓝 #74B9FF
- 健康:❤️ 珊瑚粉 #FF7675
- 科学:🔬 紫罗兰 #9B59B6
- 社会:👥 青色 #00D9A5
- 艺术:🎨 粉色 #FF7675
**特色元素:**
- 按领域区分的图标和配色
- 领域特定的教学目标
- 专业活动指导
---
## 总结
本设计文档提供了展播模式优化的完整方案,包括:
1. **儿童友好的视觉风格** - 温暖配色、圆润设计、活泼装饰
2. **美观的资源陈列** - 卡片式布局、清晰分类、易于选择
3. **流畅的播放体验** - 大按钮、自定义控件、动画过渡
4. **丰富的互动元素** - 音效反馈、动画效果、奖励机制
5. **简化的导航控制** - 大按钮、快捷键、儿童易操作
按照此设计实现,将为幼儿提供更加友好、有趣的展播体验!🎉
---
**下一步:**
1. 审阅设计文档,确认优化方向
2. 开始技术实现,按优先级逐步推进
3. 边实现边测试,收集用户反馈
*文档创建于 2026-03-11*