xuexiaole-officialWebsite/src/components/new/ClassroomMonitorSectionNew.vue
2026-05-18 15:50:48 +09:00

303 lines
15 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

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.

<script setup lang="ts">
import {
Monitor, MonitorPlay, History, Image,
Share2, Radio, Clock, Layers,
Presentation, Users, Zap,
} from 'lucide-vue-next'
import { useScrollReveal } from '@/composables/useScrollReveal'
import ClassroomMonitorMockup from '@/components/new/illustrations/ClassroomMonitorMockup.vue'
import TeacherScreenShareMockup from '@/components/new/illustrations/TeacherScreenShareMockup.vue'
const screenSharePoints = [
{ icon: Presentation, text: '管理端一键唤起,教师桌面端独立窗口推流' },
{ icon: Users, text: '全班学生端同步接收,讲解画面实时跟看' },
{ icon: Zap, text: '课件、白板、实操演示一屏直达,线上线下同堂' },
]
const { target, isVisible } = useScrollReveal()
const workflowSteps = [
{ step: '01', title: '共享屏幕讲解', desc: '课堂管控选班后点「共享屏幕」,教师端独立窗口向全班推流', highlight: true },
{ step: '02', title: '开启课堂监控', desc: '一键开启监控会话,学生端 WebSocket 联动进入投屏状态' },
{ step: '03', title: '实时截图墙', desc: '按设定间隔采集屏幕快照,网格展示全班学习画面' },
{ step: '04', title: '回溯与复盘', desc: '历史会话存档,可按学生查看全部截图记录' },
]
const features = [
{
icon: MonitorPlay,
title: '一键开启监控',
desc: '按班级控制监控会话,实时查看监控状态、开始时间与采集间隔',
color: 'cyan',
},
{
icon: Image,
title: '学生截图墙',
desc: '全班学生屏幕快照网格展示,支持自动刷新、延迟提示与单生详情',
color: 'sky',
},
{
icon: Radio,
title: '屏幕监控',
desc: '桌面客户端打开学员 JPEG 截屏监控窗口,课堂专注度一目了然',
color: 'cyan',
},
{
icon: History,
title: '历史监控',
desc: '按会话查看教师、时长、学生数与截图数,支持进入会话详情复盘',
color: 'sky',
},
{
icon: Layers,
title: '截图归档',
desc: '点击学生卡片可查看该生在单次会话中的全部截图与时间轴',
color: 'teal',
},
{
icon: Clock,
title: '心跳保活',
desc: '监控期间自动心跳与定时刷新,保障长课时课堂连接稳定',
color: 'cyan',
},
{
icon: Monitor,
title: '课堂管控中心',
desc: '班级列表集中管理共享屏幕与屏幕监控入口,管控操作一站完成',
color: 'sky',
},
]
const colorMap: Record<string, { iconBg: string; text: string; border: string }> = {
primary: { iconBg: 'bg-primary/12', text: 'text-primary', border: 'border-primary/20' },
cyan: { iconBg: 'bg-cyan-500/12', text: 'text-cyan-600', border: 'border-cyan-500/10' },
sky: { iconBg: 'bg-sky-500/12', text: 'text-sky-600', border: 'border-sky-500/10' },
teal: { iconBg: 'bg-teal-500/12', text: 'text-teal-600', border: 'border-teal-500/10' },
}
</script>
<template>
<section id="classroom-monitor" class="relative py-24 lg:py-32 bg-white overflow-hidden">
<div class="absolute top-0 left-0 right-0 h-px bg-gradient-to-r from-transparent via-cyan-500/25 to-transparent" />
<div class="absolute top-24 -left-32 w-72 h-72 rounded-full bg-cyan-500/5 blur-3xl" />
<div class="absolute bottom-16 -right-24 w-64 h-64 rounded-full bg-teal-500/5 blur-3xl" />
<div ref="target" class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div
class="text-center max-w-3xl mx-auto mb-12 lg:mb-16 transition-all duration-700"
:class="isVisible ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-8'"
>
<p class="text-sm font-semibold text-cyan-600 tracking-wider uppercase mb-3">课堂监控</p>
<h2 class="text-3xl sm:text-4xl lg:text-[2.75rem] font-extrabold text-text-heading leading-tight">
老师一讲全班跟看<span class="bg-gradient-to-r from-primary to-cyan-600 bg-clip-text text-transparent">课堂尽在掌握</span>
</h2>
<p class="text-lg text-text-muted mt-5 leading-relaxed">
<strong class="font-semibold text-text-heading">教师共享屏幕讲解</strong>让课件与演示同步到每位学生
配合课堂监控截图与历史复盘覆盖复盘完整教学闭环
</p>
</div>
<!-- 共享屏幕讲解 · 核心亮点 -->
<div
class="mb-10 lg:mb-12 transition-all duration-700"
:class="isVisible ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-8'"
:style="{ transitionDelay: isVisible ? '120ms' : '0ms' }"
>
<div class="relative overflow-visible rounded-3xl border-2 border-primary/20 bg-gradient-to-br from-primary/[0.06] via-white to-cyan-50/80 shadow-xl shadow-primary/10">
<div class="absolute top-0 right-0 w-64 h-64 rounded-full bg-primary/10 blur-3xl -translate-y-1/2 translate-x-1/3 pointer-events-none" />
<div class="absolute bottom-0 left-0 w-48 h-48 rounded-full bg-cyan-400/10 blur-3xl translate-y-1/3 -translate-x-1/4 pointer-events-none" />
<div class="relative grid lg:grid-cols-2 gap-8 lg:gap-12 p-6 sm:p-8 lg:p-10 items-center">
<div>
<span class="inline-flex items-center gap-1.5 px-3 py-1 rounded-full text-xs font-bold bg-primary text-white shadow-md shadow-primary/25 mb-4">
<Share2 class="w-3.5 h-3.5" />
核心亮点
</span>
<h3 class="text-2xl sm:text-3xl font-extrabold text-text-heading leading-snug mb-3">
教师共享屏幕讲解
</h3>
<p class="text-base text-text-muted leading-relaxed mb-6">
在管理端课堂管控选择班级点击共享屏幕即可唤起教师桌面端独立推流窗口
教师课件白板与实操画面实时同步至全班学生端线上线下同堂跟讲告别看不清跟不上
</p>
<ul class="space-y-3">
<li
v-for="point in screenSharePoints"
:key="point.text"
class="flex items-start gap-3"
>
<div class="w-9 h-9 shrink-0 rounded-xl bg-primary/10 flex items-center justify-center">
<component :is="point.icon" class="w-4 h-4 text-primary" />
</div>
<span class="text-sm text-text-body leading-relaxed pt-1.5">{{ point.text }}</span>
</li>
</ul>
</div>
<div class="relative max-w-md mx-auto lg:max-w-none w-full px-1 sm:px-2">
<TeacherScreenShareMockup />
<div class="absolute -top-2 -right-1 sm:right-4 glass-card-strong rounded-xl px-3 py-2 shadow-lg animate-float-slow">
<div class="flex items-center gap-2">
<span class="relative flex h-2 w-2">
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-red-400 opacity-75" />
<span class="relative inline-flex rounded-full h-2 w-2 bg-red-500" />
</span>
<p class="text-xs font-semibold text-text-heading">讲解推流中</p>
</div>
</div>
</div>
</div>
</div>
</div>
<p class="text-center text-sm font-medium text-cyan-700/90 mb-6">学生屏幕监控</p>
<div
class="mb-14 lg:mb-16 transition-all duration-700"
:class="isVisible ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-8'"
:style="{ transitionDelay: isVisible ? '200ms' : '0ms' }"
>
<div class="max-w-4xl mx-auto relative">
<ClassroomMonitorMockup />
<div class="absolute -top-3 -right-2 lg:right-6 glass-card-strong rounded-xl px-3.5 py-2.5 shadow-lg animate-float-slow hidden sm:block">
<div class="flex items-center gap-2">
<div class="w-7 h-7 rounded-lg bg-primary/15 flex items-center justify-center">
<Share2 class="w-4 h-4 text-primary" />
</div>
<div>
<p class="text-xs font-semibold text-text-heading">共享屏幕讲解</p>
<p class="text-xs text-primary font-medium">全班同步跟看</p>
</div>
</div>
</div>
<div class="absolute bottom-6 -left-2 lg:left-2 glass-card-strong rounded-xl px-3.5 py-2.5 shadow-lg animate-float-medium hidden sm:block">
<div class="flex items-center gap-2">
<div class="w-7 h-7 rounded-lg bg-teal-500/15 flex items-center justify-center">
<Image class="w-4 h-4 text-teal-600" />
</div>
<div>
<p class="text-xs font-semibold text-text-heading">截图自动刷新</p>
<p class="text-xs text-teal-600 font-medium">间隔 5 </p>
</div>
</div>
</div>
</div>
</div>
<div
class="mb-14 lg:mb-16 transition-all duration-700"
:class="isVisible ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-8'"
:style="{ transitionDelay: isVisible ? '280ms' : '0ms' }"
>
<div class="grid sm:grid-cols-2 lg:grid-cols-4 gap-4">
<div
v-for="(item, i) in workflowSteps"
:key="item.step"
class="relative p-5 rounded-2xl border transition-colors duration-200"
:class="item.highlight
? 'bg-gradient-to-br from-primary/[0.08] to-cyan-50/90 border-primary/25 shadow-md shadow-primary/5'
: 'bg-bg-soft/80 border-cyan-500/10'"
>
<span
class="text-xs font-bold tracking-wider"
:class="item.highlight ? 'text-primary' : 'text-cyan-600/80'"
>{{ item.step }}</span>
<h4 class="text-base font-bold text-text-heading mt-2 mb-1.5">{{ item.title }}</h4>
<p class="text-sm text-text-muted leading-relaxed">{{ item.desc }}</p>
<span
v-if="item.highlight"
class="inline-block mt-2 text-[10px] font-semibold px-2 py-0.5 rounded-full bg-primary/10 text-primary"
>推荐首选</span>
<div
v-if="i < workflowSteps.length - 1"
class="hidden lg:block absolute top-1/2 -right-2 w-4 h-px bg-cyan-300/60"
aria-hidden="true"
/>
</div>
</div>
</div>
<!-- 共享屏幕能力大卡 -->
<div
class="mb-4 transition-all duration-700"
:class="isVisible ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-6'"
:style="{ transitionDelay: isVisible ? '360ms' : '0ms' }"
>
<div class="group relative p-6 lg:p-8 rounded-2xl border-2 border-primary/25 bg-gradient-to-r from-primary/[0.06] via-white to-primary/[0.04] hover:border-primary/40 hover:shadow-xl hover:shadow-primary/10 transition-all duration-300 cursor-pointer">
<div class="flex flex-col sm:flex-row sm:items-center gap-5">
<div class="w-14 h-14 shrink-0 rounded-2xl bg-primary flex items-center justify-center shadow-lg shadow-primary/30 group-hover:scale-105 transition-transform duration-300">
<Share2 class="w-7 h-7 text-white" />
</div>
<div class="flex-1 min-w-0">
<div class="flex flex-wrap items-center gap-2 mb-1">
<h4 class="text-lg font-bold text-text-heading">教师共享屏幕讲解</h4>
<span class="text-xs font-semibold px-2.5 py-0.5 rounded-full bg-primary text-white">核心亮点</span>
</div>
<p class="text-sm text-text-muted leading-relaxed">
管理端课堂管控一键打开教师桌面端独立推流窗口课件白板实操演示同步到全班学生端线上线下混合课的首选讲解方式
</p>
</div>
</div>
</div>
</div>
<div class="grid sm:grid-cols-2 lg:grid-cols-4 gap-4">
<div
v-for="(feat, i) in features"
:key="feat.title"
class="group relative p-5 rounded-2xl bg-white border hover:border-cyan-500/25 hover:shadow-lg hover:shadow-cyan-500/5 hover:-translate-y-0.5 transition-all duration-300 cursor-pointer"
:class="[
colorMap[feat.color].border,
isVisible ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-6',
]"
:style="{ transitionDelay: isVisible ? `${440 + i * 70}ms` : '0ms', transitionDuration: '600ms' }"
>
<div class="absolute -bottom-4 -right-4 w-16 h-16 rounded-full bg-cyan-500/[0.03] group-hover:bg-cyan-500/[0.08] transition-colors duration-500" />
<div class="relative">
<div
class="w-10 h-10 rounded-xl flex items-center justify-center mb-3 group-hover:scale-110 transition-transform duration-300"
:class="colorMap[feat.color].iconBg"
>
<component :is="feat.icon" class="w-5 h-5" :class="colorMap[feat.color].text" />
</div>
<h4 class="text-base font-bold text-text-heading mb-1">{{ feat.title }}</h4>
<p class="text-sm text-text-muted leading-relaxed">{{ feat.desc }}</p>
</div>
</div>
</div>
<div
class="mt-12 lg:mt-14 p-6 lg:p-8 rounded-2xl bg-gradient-to-br from-primary/[0.06] via-cyan-50/80 to-teal-50/80 border border-primary/15 transition-all duration-700"
:class="isVisible ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-6'"
:style="{ transitionDelay: isVisible ? '750ms' : '0ms' }"
>
<div class="flex flex-col lg:flex-row lg:items-center lg:justify-between gap-4">
<div>
<p class="text-sm font-semibold text-primary mb-1">多端协同 · 讲解优先</p>
<p class="text-text-muted text-sm leading-relaxed max-w-2xl">
<strong class="text-text-heading font-medium">教师桌面端共享屏幕</strong>负责向全班推流讲解
管理端负责监控开关与截图查看学生端接收推流并上报屏幕
三者配合先讲清楚再看得住最后能复盘
</p>
</div>
<div class="flex flex-wrap gap-2 shrink-0">
<span class="px-3 py-1.5 text-xs font-semibold rounded-full bg-primary text-white shadow-sm">教师桌面端 · 共享屏幕</span>
<span class="px-3 py-1.5 text-xs font-medium rounded-full bg-white text-cyan-700 border border-cyan-200/80">管理端 · 课堂管控</span>
<span class="px-3 py-1.5 text-xs font-medium rounded-full bg-white text-sky-700 border border-sky-200/80">学生体验端</span>
</div>
</div>
</div>
</div>
</section>
</template>
<style scoped>
@keyframes float-slow {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-10px); }
}
@keyframes float-medium {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-7px); }
}
.animate-float-slow { animation: float-slow 5s ease-in-out infinite; }
.animate-float-medium { animation: float-medium 4s ease-in-out infinite 0.5s; }
</style>