|
|
@@ -0,0 +1,1185 @@
|
|
|
+<template>
|
|
|
+ <view class="page">
|
|
|
+ <view class="video-wrap">
|
|
|
+ <video
|
|
|
+ :key="activeIndex"
|
|
|
+ @timeupdate="onTimeUpdate"
|
|
|
+ @progress="progressChange"
|
|
|
+ @error="videoErrorCallback"
|
|
|
+ @play="getPlay"
|
|
|
+ @pause="getPause"
|
|
|
+ @ended="getEnded"
|
|
|
+ @fullscreenchange="fullscreenchange"
|
|
|
+ :title="courseInfo.title"
|
|
|
+ style="width: 100%;height: 420rpx;"
|
|
|
+ :poster="poster"
|
|
|
+ id="video-content-box"
|
|
|
+ controls
|
|
|
+ :autoplay="true"
|
|
|
+ :auto-pause-if-open-native="true"
|
|
|
+ :auto-pause-if-navigate="true"
|
|
|
+ :enable-progress-gesture="false"
|
|
|
+ :show-progress="true"
|
|
|
+ :picture-in-picture-mode="[]"
|
|
|
+ :show-background-playback-button="false"
|
|
|
+ :src="videoUrl"
|
|
|
+ >
|
|
|
+ <cover-view class="back-box" :style="{'top':statusBarHeight}" @click="goBack()">
|
|
|
+ <cover-image src="@/static/images/return_black.png" style="width: 24px;height: 24px;"></cover-image>
|
|
|
+ </cover-view>
|
|
|
+ </video>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <scroll-view class="page-scroll" scroll-y>
|
|
|
+ <view class="content">
|
|
|
+ <view class="course-title">{{ courseInfo.title }}</view>
|
|
|
+ <view class="course-desc">{{ courseInfo.desc }}</view>
|
|
|
+ <view class="course-views">{{ courseInfo.views }}次播放</view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="section-head">
|
|
|
+ <view class="left">
|
|
|
+ <view class="dot"></view>
|
|
|
+ <text class="section-title">课程目录</text>
|
|
|
+ </view>
|
|
|
+ <text class="count" @click="showCatalog = true">共{{ catalogList.length }}节 ›</text>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <scroll-view class="catalog-scroll" scroll-x>
|
|
|
+ <view class="catalog-row">
|
|
|
+ <view
|
|
|
+ v-for="(item, index) in catalogList"
|
|
|
+ :key="item.id"
|
|
|
+ class="catalog-item"
|
|
|
+ :class="{ active: activeIndex === index }"
|
|
|
+ @click="selectCourse(index)"
|
|
|
+ >
|
|
|
+ <view class="catalog-top">
|
|
|
+ <view class="catalog-index-wrap">
|
|
|
+ <text class="catalog-index">第{{ index + 1 }}讲</text>
|
|
|
+ <view class="catalog-active-dot" v-if="activeIndex === index"></view>
|
|
|
+ </view>
|
|
|
+ <text class="free-tag" v-if="item.free">限时免费</text>
|
|
|
+ </view>
|
|
|
+ <view class="catalog-name ellipsis2">{{ item.name }}</view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </scroll-view>
|
|
|
+
|
|
|
+ <view class="comment-wrap">
|
|
|
+ <view class="comment-title">评论</view>
|
|
|
+ <view class="comment-item" v-for="item in comments" :key="item.id">
|
|
|
+ <image class="avatar" :src="item.avatar" mode="aspectFill"></image>
|
|
|
+ <view class="comment-main">
|
|
|
+ <view class="name">{{ item.name }}</view>
|
|
|
+ <view class="time">{{ item.time }}</view>
|
|
|
+ <view class="text">{{ item.content }}</view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="bottom-space"></view>
|
|
|
+ </scroll-view>
|
|
|
+
|
|
|
+ <view class="answer-entry" @click="openAnswerPopup">
|
|
|
+ <image class="gift-icon" src="@/static/images/new/jpk.png" mode="aspectFit"></image>
|
|
|
+ <view class="answer-tip" :class="{ done: hasAward }">{{ answerEntryTip }}</view>
|
|
|
+ <view class="answer-btn">答题</view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="bottom-bar">
|
|
|
+ <view class="input">发表我的态度</view>
|
|
|
+ <view class="send-btn">发送</view>
|
|
|
+ <view class="share-btn" @click="handleShare">
|
|
|
+ <text class="share-icon">↗</text>
|
|
|
+ <text>分享</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="answer-mask" v-if="showAnswerPopup" @click="closeAnswerPopup">
|
|
|
+ <view class="answer-panel" @click.stop>
|
|
|
+ <view class="answer-head">
|
|
|
+ <view class="left">
|
|
|
+ <view class="dot"></view>
|
|
|
+ <text class="section-title">问答题</text>
|
|
|
+ </view>
|
|
|
+ <view class="close-btn" @click="closeAnswerPopup">✕</view>
|
|
|
+ </view>
|
|
|
+ <view class="answer-divider"></view>
|
|
|
+ <view class="question-title">{{ answerQuestion.title }}</view>
|
|
|
+ <view
|
|
|
+ v-for="(option, index) in answerQuestion.options"
|
|
|
+ :key="option.value"
|
|
|
+ class="answer-option"
|
|
|
+ :class="{ active: selectedAnswer === option.value, disabled: !canAnswer }"
|
|
|
+ @click="selectAnswer(option.value)"
|
|
|
+ >
|
|
|
+ {{ option.label }}
|
|
|
+ </view>
|
|
|
+ <view
|
|
|
+ class="submit-btn"
|
|
|
+ :class="{ active: canAnswer && selectedAnswer, disabled: !canAnswer || !selectedAnswer }"
|
|
|
+ @click="submitAnswer"
|
|
|
+ >
|
|
|
+ {{ canAnswer ? "提交答案" : ("再观看" + answerCountdownText + "可答题") }}
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="answer-result-mask" v-if="showAnswerResultPopup" @click="closeAnswerResultPopup">
|
|
|
+ <view class="answer-result-panel" @click.stop>
|
|
|
+ <view class="result-title">{{ resultConfig.title }}</view>
|
|
|
+ <view class="result-subtitle" v-if="answerResultType === 'success'">
|
|
|
+ 获得<text class="result-score">{{ awardScore }}</text>积分,自动到账
|
|
|
+ </view>
|
|
|
+ <view class="result-subtitle" v-else>{{ resultConfig.subtitle }}</view>
|
|
|
+ <view class="result-chance">{{ resultConfig.chanceText }}</view>
|
|
|
+ <view class="result-primary-btn" v-if="resultConfig.showPrimary" @click="goToIntegralMall">
|
|
|
+ 前往积分商城兑换
|
|
|
+ </view>
|
|
|
+ <view class="result-second-btn" @click="closeAnswerResultPopup">继续观看</view>
|
|
|
+ </view>
|
|
|
+ <view class="result-close" @click.stop="closeAnswerResultPopup">✕</view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="share-mask" v-if="showSharePopup" @click="closeSharePopup">
|
|
|
+ <view class="share-panel" @click.stop>
|
|
|
+ <view class="share-card">
|
|
|
+ <view class="share-item" @click="onShareSelect('wechat')">
|
|
|
+ <view class="share-avatar wechat"></view>
|
|
|
+ <text class="share-text">分享给微信好友</text>
|
|
|
+ </view>
|
|
|
+ <view class="share-item" @click="onShareSelect('moments')">
|
|
|
+ <view class="share-avatar moments"></view>
|
|
|
+ <text class="share-text">分享到朋友圈</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="cancel-btn" @click="closeSharePopup">取消</view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="popup-mask" v-if="showCatalog" @click="showCatalog = false">
|
|
|
+ <view class="popup-panel" @click.stop>
|
|
|
+ <view class="popup-head">
|
|
|
+ <view class="left">
|
|
|
+ <view class="dot"></view>
|
|
|
+ <text class="section-title">课程目录</text>
|
|
|
+ </view>
|
|
|
+ <view class="close-btn" @click="showCatalog = false">✕</view>
|
|
|
+ </view>
|
|
|
+ <scroll-view class="popup-scroll" scroll-y>
|
|
|
+ <view
|
|
|
+ v-for="(item, index) in catalogList"
|
|
|
+ :key="item.id"
|
|
|
+ class="popup-item"
|
|
|
+ :class="{ active: activeIndex === index }"
|
|
|
+ @click="selectCourse(index)"
|
|
|
+ >
|
|
|
+ <view class="catalog-top">
|
|
|
+ <text class="catalog-index">第{{ index + 1 }}讲</text>
|
|
|
+ <text class="free-tag" v-if="item.free">限时免费</text>
|
|
|
+ </view>
|
|
|
+ <view class="popup-name">{{ item.name }}</view>
|
|
|
+ </view>
|
|
|
+ </scroll-view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+export default {
|
|
|
+ computed: {
|
|
|
+ poster() {
|
|
|
+ const item = this.catalogList[this.activeIndex];
|
|
|
+ return (item && item.poster) || this.courseInfo.cover;
|
|
|
+ },
|
|
|
+ canAnswer() {
|
|
|
+ return this.answerCountdown <= 0;
|
|
|
+ },
|
|
|
+ answerCountdownText() {
|
|
|
+ const second = this.answerCountdown < 0 ? 0 : this.answerCountdown;
|
|
|
+ const minuteNum = Math.floor(second / 60);
|
|
|
+ const secondNum = second % 60;
|
|
|
+ if (minuteNum > 0) {
|
|
|
+ return minuteNum + "分" + secondNum + "秒";
|
|
|
+ }
|
|
|
+ return secondNum + "秒";
|
|
|
+ },
|
|
|
+ answerEntryTip() {
|
|
|
+ if (this.hasAward) {
|
|
|
+ return "已得" + this.awardScore + "积分";
|
|
|
+ }
|
|
|
+ if (this.attemptsLeft <= 0) {
|
|
|
+ return "未答对 明天再来";
|
|
|
+ }
|
|
|
+ if (!this.canAnswer) {
|
|
|
+ return "再观看" + this.answerCountdownText + "可答题得奖励";
|
|
|
+ }
|
|
|
+ return "答题得奖励";
|
|
|
+ },
|
|
|
+ resultConfig() {
|
|
|
+ const configMap = {
|
|
|
+ success: {
|
|
|
+ title: "恭喜你,回答正确",
|
|
|
+ subtitle: "",
|
|
|
+ chanceText: "每节课拥有" + this.maxAttempts + "次答题机会",
|
|
|
+ showPrimary: true
|
|
|
+ },
|
|
|
+ fail: {
|
|
|
+ title: "很遗憾答错了",
|
|
|
+ subtitle: "请继续努力哦",
|
|
|
+ chanceText: "每节课拥有" + this.maxAttempts + "次答题机会",
|
|
|
+ showPrimary: false
|
|
|
+ },
|
|
|
+ exhausted: {
|
|
|
+ title: "今天答题次数已用完",
|
|
|
+ subtitle: "明天再来哦",
|
|
|
+ chanceText: "每节课拥有" + this.maxAttempts + "次答题机会",
|
|
|
+ showPrimary: false
|
|
|
+ }
|
|
|
+ };
|
|
|
+ return configMap[this.answerResultType];
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ statusBarHeight: uni.getSystemInfoSync().statusBarHeight + 'px',
|
|
|
+ isShu: false,
|
|
|
+ isFull: false,
|
|
|
+ videoUrl: "http://bjzmkytcpv.ylrzcloud.com/course/202647/1775560007686.mp4",
|
|
|
+ videoContext: null,
|
|
|
+ playTime: 0,
|
|
|
+ videoDuration: 0,
|
|
|
+ bufferRate: 0,
|
|
|
+ errorCount: 0,
|
|
|
+ showCatalog: false,
|
|
|
+ showSharePopup: false,
|
|
|
+ showAnswerPopup: false,
|
|
|
+ showAnswerResultPopup: false,
|
|
|
+ activeIndex: 0,
|
|
|
+ answerTimer: null,
|
|
|
+ answerCountdown: 90,
|
|
|
+ selectedAnswer: "",
|
|
|
+ answerResultType: "success",
|
|
|
+ maxAttempts: 3,
|
|
|
+ attemptsLeft: 3,
|
|
|
+ correctAnswer: "C",
|
|
|
+ awardScore: 20,
|
|
|
+ hasAward: false,
|
|
|
+ answerQuestion: {
|
|
|
+ title: "1.《大美国医》药王级鹿茸粉单选特价供应货源还剩下不足多少盒?",
|
|
|
+ options: [
|
|
|
+ { value: "A", label: "A.800 盒" },
|
|
|
+ { value: "B", label: "B.1000 盒" },
|
|
|
+ { value: "C", label: "C.1500 盒" },
|
|
|
+ { value: "D", label: "D.5000 盒" }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ courseInfo: {
|
|
|
+ title: "邹方斌讲《毛笔书法修心课》",
|
|
|
+ desc: "零基础名师教学零起步,邹方斌讲《毛笔书法修心课》在家也能轻松学书法。",
|
|
|
+ views: "4127946",
|
|
|
+ duration: "45:38",
|
|
|
+ cover: "https://picsum.photos/900/520"
|
|
|
+ },
|
|
|
+ catalogList: [
|
|
|
+ { id: 1, name: "毛笔书法修心课》在家也能学", free: true },
|
|
|
+ { id: 2, name: "毛笔书法修心课》在家也能轻松学", free: true },
|
|
|
+ { id: 3, name: "毛笔书法修心课》在家也能轻松学", free: false },
|
|
|
+ { id: 4, name: "书法艺术概论", free: true },
|
|
|
+ { id: 5, name: "运笔的基础知识", free: true },
|
|
|
+ { id: 6, name: "字形结构与章法", free: true }
|
|
|
+ ],
|
|
|
+ comments: [
|
|
|
+ {
|
|
|
+ id: 1,
|
|
|
+ name: "app用户32781",
|
|
|
+ time: "今天08:38",
|
|
|
+ content: "讲的真好,循序渐进,让小白也很容易能入门学习!",
|
|
|
+ avatar: "https://picsum.photos/80/80?1"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 2,
|
|
|
+ name: "app用户32781",
|
|
|
+ time: "2026-02-10 12:37",
|
|
|
+ content: "讲的通俗易懂,很好!",
|
|
|
+ avatar: "https://picsum.photos/80/80?2"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 3,
|
|
|
+ name: "app用户32781",
|
|
|
+ time: "2026-02-10 12:37",
|
|
|
+ content: "赞赞赞,我要好好学!",
|
|
|
+ avatar: "https://picsum.photos/80/80?3"
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ };
|
|
|
+ },
|
|
|
+ onLoad() {
|
|
|
+ this.initLessonVideo();
|
|
|
+ this.startAnswerCountdown();
|
|
|
+ },
|
|
|
+ onReady() {
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.videoContext = uni.createVideoContext("video-content-box", this);
|
|
|
+ this.tryPlayVideo();
|
|
|
+ });
|
|
|
+ },
|
|
|
+ onUnload() {
|
|
|
+ this.clearAnswerTimer();
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ /** 进入页或切课后尝试自动播放(部分端需与 autoplay 配合) */
|
|
|
+ tryPlayVideo() {
|
|
|
+ if (!this.videoContext) {
|
|
|
+ this.videoContext = uni.createVideoContext("video-content-box", this);
|
|
|
+ }
|
|
|
+ const ctx = this.videoContext;
|
|
|
+ if (!ctx || !ctx.play) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.$nextTick(() => {
|
|
|
+ setTimeout(() => {
|
|
|
+ try {
|
|
|
+ ctx.play();
|
|
|
+ } catch (e) {
|
|
|
+ console.warn("tryPlayVideo", e);
|
|
|
+ }
|
|
|
+ }, 100);
|
|
|
+ });
|
|
|
+ },
|
|
|
+ initLessonVideo() {
|
|
|
+ const item = this.catalogList[this.activeIndex];
|
|
|
+ },
|
|
|
+ onTimeUpdate(e) {
|
|
|
+ const d = (e && e.detail) || {};
|
|
|
+ this.playTime = Math.floor(d.currentTime || 0);
|
|
|
+ if (d.duration) {
|
|
|
+ this.videoDuration = d.duration;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ progressChange(e) {
|
|
|
+ const d = (e && e.detail) || {};
|
|
|
+ if (d.buffered != null) {
|
|
|
+ this.bufferRate = d.buffered;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ videoErrorCallback(e) {
|
|
|
+ this.errorCount += 1;
|
|
|
+ console.error("courseDetail video error", e);
|
|
|
+ if (this.errorCount > 3) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ uni.showToast({
|
|
|
+ title: "视频加载失败,请稍后重试",
|
|
|
+ icon: "none"
|
|
|
+ });
|
|
|
+ },
|
|
|
+ getPlay() {
|
|
|
+ this.errorCount = 0;
|
|
|
+ },
|
|
|
+ getPause() {},
|
|
|
+ getEnded() {
|
|
|
+ if (this.videoDuration) {
|
|
|
+ this.playTime = Math.floor(this.videoDuration);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ fullscreenchange(e) {
|
|
|
+ const d = (e && e.detail) || {};
|
|
|
+ this.isFull = !!d.fullScreen;
|
|
|
+ },
|
|
|
+ startAnswerCountdown() {
|
|
|
+ this.clearAnswerTimer();
|
|
|
+ this.answerTimer = setInterval(() => {
|
|
|
+ if (this.answerCountdown <= 0) {
|
|
|
+ this.clearAnswerTimer();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.answerCountdown -= 1;
|
|
|
+ }, 1000);
|
|
|
+ },
|
|
|
+ clearAnswerTimer() {
|
|
|
+ if (this.answerTimer) {
|
|
|
+ clearInterval(this.answerTimer);
|
|
|
+ this.answerTimer = null;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ openAnswerPopup() {
|
|
|
+ if (this.attemptsLeft <= 0) {
|
|
|
+ this.answerResultType = "exhausted";
|
|
|
+ this.showAnswerResultPopup = true;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.showAnswerPopup = true;
|
|
|
+ },
|
|
|
+ closeAnswerPopup() {
|
|
|
+ this.showAnswerPopup = false;
|
|
|
+ },
|
|
|
+ closeAnswerResultPopup() {
|
|
|
+ this.showAnswerResultPopup = false;
|
|
|
+ },
|
|
|
+ selectAnswer(value) {
|
|
|
+ if (!this.canAnswer) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.selectedAnswer = value;
|
|
|
+ },
|
|
|
+ submitAnswer() {
|
|
|
+ if (!this.canAnswer || !this.selectedAnswer) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.attemptsLeft -= 1;
|
|
|
+ this.showAnswerPopup = false;
|
|
|
+ if (this.selectedAnswer === this.correctAnswer) {
|
|
|
+ this.answerResultType = "success";
|
|
|
+ this.hasAward = true;
|
|
|
+ } else if (this.attemptsLeft <= 0) {
|
|
|
+ this.answerResultType = "exhausted";
|
|
|
+ } else {
|
|
|
+ this.answerResultType = "fail";
|
|
|
+ }
|
|
|
+ this.showAnswerResultPopup = true;
|
|
|
+ this.selectedAnswer = "";
|
|
|
+ },
|
|
|
+ goToIntegralMall() {
|
|
|
+ this.showAnswerResultPopup = false;
|
|
|
+ uni.navigateTo({
|
|
|
+ url: "/pages_user/user/integralGoodsList"
|
|
|
+ });
|
|
|
+ },
|
|
|
+ goBack() {
|
|
|
+ uni.navigateBack({
|
|
|
+ delta: 1,
|
|
|
+ fail: () => {
|
|
|
+ uni.switchTab({
|
|
|
+ url: "/pages/home/index"
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ selectCourse(index) {
|
|
|
+ this.activeIndex = index;
|
|
|
+ this.showCatalog = false;
|
|
|
+ this.initLessonVideo();
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.videoContext = uni.createVideoContext("video-content-box", this);
|
|
|
+ this.tryPlayVideo();
|
|
|
+ });
|
|
|
+ },
|
|
|
+ handleShare() {
|
|
|
+ this.showSharePopup = true;
|
|
|
+ },
|
|
|
+ closeSharePopup() {
|
|
|
+ this.showSharePopup = false;
|
|
|
+ },
|
|
|
+ onShareSelect(type) {
|
|
|
+ this.showSharePopup = false;
|
|
|
+ const shareText = type === "wechat" ? "微信好友" : "朋友圈";
|
|
|
+ uni.showToast({
|
|
|
+ title: "分享至" + shareText + "待接入",
|
|
|
+ icon: "none"
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+.page {
|
|
|
+ background: #f6f6f6;
|
|
|
+ height: 100vh;
|
|
|
+}
|
|
|
+.back-box{
|
|
|
+ position: fixed;
|
|
|
+ left:12px;
|
|
|
+ z-index:9999
|
|
|
+}
|
|
|
+.page-scroll {
|
|
|
+ height: calc(100vh - 118rpx);
|
|
|
+ padding-top: 420rpx;
|
|
|
+ box-sizing: border-box;
|
|
|
+}
|
|
|
+
|
|
|
+.video-wrap {
|
|
|
+ position: fixed;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ z-index: 20;
|
|
|
+ width: 100%;
|
|
|
+ height: 420rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.video-cover {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+}
|
|
|
+
|
|
|
+.video-mask {
|
|
|
+ position: absolute;
|
|
|
+ inset: 0;
|
|
|
+ background: rgba(0, 0, 0, 0.2);
|
|
|
+}
|
|
|
+
|
|
|
+.top-left {
|
|
|
+ position: absolute;
|
|
|
+ left: 24rpx;
|
|
|
+ top: 24rpx;
|
|
|
+ color: #fff;
|
|
|
+ font-size: 56rpx;
|
|
|
+ z-index: 2;
|
|
|
+}
|
|
|
+
|
|
|
+.top-right {
|
|
|
+ position: absolute;
|
|
|
+ right: 24rpx;
|
|
|
+ top: 24rpx;
|
|
|
+ display: flex;
|
|
|
+ gap: 12rpx;
|
|
|
+ z-index: 2;
|
|
|
+}
|
|
|
+
|
|
|
+.dot-btn {
|
|
|
+ min-width: 56rpx;
|
|
|
+ height: 56rpx;
|
|
|
+ padding: 0 18rpx;
|
|
|
+ border-radius: 28rpx;
|
|
|
+ background: rgba(0, 0, 0, 0.45);
|
|
|
+ color: #fff;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ font-size: 26rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.video-control {
|
|
|
+ position: absolute;
|
|
|
+ bottom: 18rpx;
|
|
|
+ left: 24rpx;
|
|
|
+ right: 24rpx;
|
|
|
+ z-index: 2;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ color: #fff;
|
|
|
+ font-size: 24rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.play-icon {
|
|
|
+ margin-right: 12rpx;
|
|
|
+ font-size: 28rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.time-text {
|
|
|
+ min-width: 70rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.progress-line {
|
|
|
+ flex: 1;
|
|
|
+ height: 4rpx;
|
|
|
+ margin: 0 14rpx;
|
|
|
+ background: rgba(255, 255, 255, 0.85);
|
|
|
+}
|
|
|
+
|
|
|
+.content {
|
|
|
+ background: #fff;
|
|
|
+ padding: 24rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.course-title {
|
|
|
+ font-size: 42rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #222;
|
|
|
+ line-height: 58rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.course-desc {
|
|
|
+ margin-top: 14rpx;
|
|
|
+ font-size: 32rpx;
|
|
|
+ color: #666;
|
|
|
+ line-height: 46rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.course-views {
|
|
|
+ margin-top: 14rpx;
|
|
|
+ font-size: 34rpx;
|
|
|
+ color: #999;
|
|
|
+}
|
|
|
+
|
|
|
+.section-head {
|
|
|
+ margin-top: 14rpx;
|
|
|
+ padding: 18rpx 24rpx 14rpx;
|
|
|
+ background: #fff;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+}
|
|
|
+
|
|
|
+.left {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+
|
|
|
+.dot {
|
|
|
+ width: 20rpx;
|
|
|
+ height: 20rpx;
|
|
|
+ background: #f23b4d;
|
|
|
+ border-radius: 4rpx;
|
|
|
+ margin-right: 12rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.section-title {
|
|
|
+ font-size: 38rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #222;
|
|
|
+}
|
|
|
+
|
|
|
+.count {
|
|
|
+ color: #9a9a9a;
|
|
|
+ font-size: 30rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.catalog-scroll {
|
|
|
+ padding: 4rpx 24rpx 20rpx;
|
|
|
+ background: #fff;
|
|
|
+ white-space: nowrap;
|
|
|
+}
|
|
|
+
|
|
|
+.catalog-row {
|
|
|
+ display: inline-flex;
|
|
|
+ gap: 12rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.catalog-item {
|
|
|
+ width: 280rpx;
|
|
|
+ min-height: 192rpx;
|
|
|
+ background: #FFF0F2;
|
|
|
+ border-radius: 20rpx;
|
|
|
+ background: #f2f3f6;
|
|
|
+ padding:24rpx;
|
|
|
+ box-sizing: border-box;
|
|
|
+ position: relative;
|
|
|
+}
|
|
|
+
|
|
|
+.catalog-item.active {
|
|
|
+ background: #ffeef1;
|
|
|
+ border-color: #ffd7de;
|
|
|
+}
|
|
|
+
|
|
|
+.catalog-top {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+}
|
|
|
+
|
|
|
+.catalog-index-wrap {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+
|
|
|
+.catalog-index {
|
|
|
+ font-family: PingFangSC, PingFang SC;
|
|
|
+ font-weight: 600;
|
|
|
+ font-size: 32rpx;
|
|
|
+ color: #FF233C;
|
|
|
+ line-height: 44rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.catalog-active-dot {
|
|
|
+ width: 18rpx;
|
|
|
+ height: 18rpx;
|
|
|
+ margin-left: 8rpx;
|
|
|
+ border-radius: 50%;
|
|
|
+ background: #ff2b49;
|
|
|
+ position: relative;
|
|
|
+}
|
|
|
+
|
|
|
+.catalog-active-dot::after {
|
|
|
+ content: "";
|
|
|
+ position: absolute;
|
|
|
+ left: 5rpx;
|
|
|
+ top: 5rpx;
|
|
|
+ width: 8rpx;
|
|
|
+ height: 8rpx;
|
|
|
+ border-radius: 50%;
|
|
|
+ background: #fff;
|
|
|
+}
|
|
|
+
|
|
|
+.free-tag {
|
|
|
+ position: absolute;
|
|
|
+ right: 0;
|
|
|
+ top:0;
|
|
|
+ padding:2rpx 10rpx;
|
|
|
+ background: #ff2b49;
|
|
|
+ border-radius: 0rpx 20rpx 0rpx 20rpx;
|
|
|
+ font-family: PingFangSC, PingFang SC;
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #FFFFFF;
|
|
|
+ line-height: 40rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.catalog-name {
|
|
|
+ margin-top: 12rpx;
|
|
|
+ font-family: PingFangSC, PingFang SC;
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 32rpx;
|
|
|
+ color: rgba(0,0,0,0.65);
|
|
|
+ line-height: 44rpx;
|
|
|
+ white-space: normal;
|
|
|
+ word-break: break-all;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ display: -webkit-box;
|
|
|
+ -webkit-line-clamp: 2;
|
|
|
+ -webkit-box-orient: vertical;
|
|
|
+}
|
|
|
+
|
|
|
+.comment-wrap {
|
|
|
+ margin-top: 14rpx;
|
|
|
+ background: #fff;
|
|
|
+ padding: 24rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.comment-title {
|
|
|
+ font-size: 42rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #222;
|
|
|
+ margin-bottom: 16rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.comment-item {
|
|
|
+ display: flex;
|
|
|
+ padding: 14rpx 0;
|
|
|
+}
|
|
|
+
|
|
|
+.avatar {
|
|
|
+ width: 72rpx;
|
|
|
+ height: 72rpx;
|
|
|
+ border-radius: 50%;
|
|
|
+ margin-right: 16rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.comment-main {
|
|
|
+ flex: 1;
|
|
|
+}
|
|
|
+
|
|
|
+.name {
|
|
|
+ font-size: 36rpx;
|
|
|
+ color: #333;
|
|
|
+ font-weight: 600;
|
|
|
+}
|
|
|
+
|
|
|
+.time {
|
|
|
+ font-size: 30rpx;
|
|
|
+ color: #999;
|
|
|
+ margin-top: 2rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.text {
|
|
|
+ font-size: 36rpx;
|
|
|
+ color: #333;
|
|
|
+ line-height: 48rpx;
|
|
|
+ margin-top: 8rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.bottom-space {
|
|
|
+ height: 40rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.answer-entry {
|
|
|
+ position: fixed;
|
|
|
+ right: 16rpx;
|
|
|
+ bottom: 210rpx;
|
|
|
+ z-index: 28;
|
|
|
+ width: 146rpx;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+
|
|
|
+.gift-icon {
|
|
|
+ width: 128rpx;
|
|
|
+ height: 78rpx;
|
|
|
+ margin-bottom: -4rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.answer-tip {
|
|
|
+ width: 146rpx;
|
|
|
+ background: #ffe08b;
|
|
|
+ border: 2rpx solid #f5cd62;
|
|
|
+ border-radius: 14rpx;
|
|
|
+ font-size: 34rpx;
|
|
|
+ line-height: 42rpx;
|
|
|
+ padding: 6rpx 10rpx;
|
|
|
+ color: #ff2b49;
|
|
|
+ text-align: center;
|
|
|
+ box-sizing: border-box;
|
|
|
+}
|
|
|
+
|
|
|
+.answer-tip.done {
|
|
|
+ border-color: #f2be3f;
|
|
|
+ color: #c53533;
|
|
|
+}
|
|
|
+
|
|
|
+.answer-btn {
|
|
|
+ margin-top: 8rpx;
|
|
|
+ width: 116rpx;
|
|
|
+ height: 62rpx;
|
|
|
+ border-radius: 32rpx;
|
|
|
+ background: #ff3b57;
|
|
|
+ color: #fff;
|
|
|
+ font-size: 38rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+}
|
|
|
+
|
|
|
+.bottom-bar {
|
|
|
+ position: fixed;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ bottom: 0;
|
|
|
+ height: 118rpx;
|
|
|
+ background: #fff;
|
|
|
+ border-top: 1rpx solid #eee;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ padding: 0 18rpx;
|
|
|
+ box-sizing: border-box;
|
|
|
+}
|
|
|
+
|
|
|
+.input {
|
|
|
+ flex: 1;
|
|
|
+ height: 70rpx;
|
|
|
+ background: #f3f3f3;
|
|
|
+ border-radius: 35rpx;
|
|
|
+ padding: 0 24rpx;
|
|
|
+ color: #bbb;
|
|
|
+ font-size: 30rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+
|
|
|
+.send-btn {
|
|
|
+ margin-left: 14rpx;
|
|
|
+ width: 146rpx;
|
|
|
+ height: 70rpx;
|
|
|
+ background: #ff3b57;
|
|
|
+ border-radius: 35rpx;
|
|
|
+ color: #fff;
|
|
|
+ font-size: 34rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+}
|
|
|
+
|
|
|
+.share-btn {
|
|
|
+ width: 88rpx;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #222;
|
|
|
+}
|
|
|
+
|
|
|
+.share-icon {
|
|
|
+ color: #ff3b57;
|
|
|
+ font-size: 36rpx;
|
|
|
+ line-height: 1;
|
|
|
+}
|
|
|
+
|
|
|
+.share-mask {
|
|
|
+ position: fixed;
|
|
|
+ inset: 0;
|
|
|
+ background: rgba(0, 0, 0, 0.45);
|
|
|
+ z-index: 120;
|
|
|
+ display: flex;
|
|
|
+ align-items: flex-end;
|
|
|
+}
|
|
|
+
|
|
|
+.share-panel {
|
|
|
+ width: 100%;
|
|
|
+ padding: 20rpx 20rpx 28rpx;
|
|
|
+ box-sizing: border-box;
|
|
|
+}
|
|
|
+
|
|
|
+.share-card {
|
|
|
+ background: #fff;
|
|
|
+ border-radius: 20rpx;
|
|
|
+ overflow: hidden;
|
|
|
+}
|
|
|
+
|
|
|
+.share-item {
|
|
|
+ height: 106rpx;
|
|
|
+ padding: 0 28rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ background: #fff;
|
|
|
+}
|
|
|
+
|
|
|
+.share-item + .share-item {
|
|
|
+ border-top: 1rpx solid #f0f0f0;
|
|
|
+}
|
|
|
+
|
|
|
+.share-avatar {
|
|
|
+ width: 52rpx;
|
|
|
+ height: 52rpx;
|
|
|
+ border-radius: 50%;
|
|
|
+ margin-right: 18rpx;
|
|
|
+ flex-shrink: 0;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #fff;
|
|
|
+}
|
|
|
+
|
|
|
+.wechat {
|
|
|
+ background: #1fc48a;
|
|
|
+}
|
|
|
+
|
|
|
+.moments {
|
|
|
+ background: conic-gradient(#f8c11b 0deg, #65ca59 130deg, #48b4f8 250deg, #f8c11b 360deg);
|
|
|
+}
|
|
|
+
|
|
|
+.share-text {
|
|
|
+ font-size: 36rpx;
|
|
|
+ color: #333;
|
|
|
+}
|
|
|
+
|
|
|
+.cancel-btn {
|
|
|
+ margin-top: 14rpx;
|
|
|
+ height: 94rpx;
|
|
|
+ background: #fff;
|
|
|
+ border-radius: 47rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ color: #333;
|
|
|
+ font-size: 38rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.answer-mask {
|
|
|
+ position: fixed;
|
|
|
+ inset: 0;
|
|
|
+ background: rgba(0, 0, 0, 0.45);
|
|
|
+ display: flex;
|
|
|
+ align-items: flex-end;
|
|
|
+ z-index: 130;
|
|
|
+}
|
|
|
+
|
|
|
+.answer-panel {
|
|
|
+ width: 100%;
|
|
|
+ background: #fff;
|
|
|
+ border-radius: 24rpx 24rpx 0 0;
|
|
|
+ padding: 20rpx 22rpx 30rpx;
|
|
|
+ box-sizing: border-box;
|
|
|
+}
|
|
|
+
|
|
|
+.answer-head {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+}
|
|
|
+
|
|
|
+.answer-divider {
|
|
|
+ margin-top: 16rpx;
|
|
|
+ height: 1rpx;
|
|
|
+ background: #ededed;
|
|
|
+}
|
|
|
+
|
|
|
+.question-title {
|
|
|
+ margin-top: 18rpx;
|
|
|
+ font-size: 46rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #222;
|
|
|
+ line-height: 60rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.answer-option {
|
|
|
+ margin-top: 18rpx;
|
|
|
+ background: #f3f4f7;
|
|
|
+ border-radius: 16rpx;
|
|
|
+ padding: 22rpx 24rpx;
|
|
|
+ font-size: 42rpx;
|
|
|
+ color: #333;
|
|
|
+ line-height: 48rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.answer-option.active {
|
|
|
+ background: #ffedf0;
|
|
|
+ color: #ff2b49;
|
|
|
+ font-weight: 600;
|
|
|
+}
|
|
|
+
|
|
|
+.answer-option.disabled {
|
|
|
+ color: #4a4a4a;
|
|
|
+}
|
|
|
+
|
|
|
+.submit-btn {
|
|
|
+ margin: 48rpx auto 0;
|
|
|
+ width: 690rpx;
|
|
|
+ max-width: 100%;
|
|
|
+ height: 88rpx;
|
|
|
+ border-radius: 44rpx;
|
|
|
+ background: #c3c4c8;
|
|
|
+ color: #fff;
|
|
|
+ font-size: 40rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+}
|
|
|
+
|
|
|
+.submit-btn.active {
|
|
|
+ background: #ff3b57;
|
|
|
+}
|
|
|
+
|
|
|
+.submit-btn.disabled {
|
|
|
+ background: #c3c4c8;
|
|
|
+}
|
|
|
+
|
|
|
+.answer-result-mask {
|
|
|
+ position: fixed;
|
|
|
+ inset: 0;
|
|
|
+ background: rgba(0, 0, 0, 0.45);
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ z-index: 135;
|
|
|
+}
|
|
|
+
|
|
|
+.answer-result-panel {
|
|
|
+ width: 660rpx;
|
|
|
+ background: #fff;
|
|
|
+ border-radius: 28rpx;
|
|
|
+ padding: 34rpx 34rpx 26rpx;
|
|
|
+ box-sizing: border-box;
|
|
|
+ text-align: center;
|
|
|
+}
|
|
|
+
|
|
|
+.result-title {
|
|
|
+ font-size: 52rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #111;
|
|
|
+ line-height: 72rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.result-subtitle {
|
|
|
+ margin-top: 24rpx;
|
|
|
+ font-size: 46rpx;
|
|
|
+ color: #333;
|
|
|
+ line-height: 62rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.result-score {
|
|
|
+ color: #ff2b49;
|
|
|
+ font-size: 56rpx;
|
|
|
+ font-weight: 600;
|
|
|
+}
|
|
|
+
|
|
|
+.result-chance {
|
|
|
+ margin-top: 18rpx;
|
|
|
+ font-size: 38rpx;
|
|
|
+ color: #666;
|
|
|
+ line-height: 52rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.result-primary-btn {
|
|
|
+ margin-top: 28rpx;
|
|
|
+ height: 84rpx;
|
|
|
+ border-radius: 42rpx;
|
|
|
+ background: #ff3b57;
|
|
|
+ color: #fff;
|
|
|
+ font-size: 40rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+}
|
|
|
+
|
|
|
+.result-second-btn {
|
|
|
+ margin-top: 22rpx;
|
|
|
+ height: 84rpx;
|
|
|
+ border-radius: 42rpx;
|
|
|
+ border: 2rpx solid #ff3b57;
|
|
|
+ color: #ff3b57;
|
|
|
+ font-size: 40rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+}
|
|
|
+
|
|
|
+.result-close {
|
|
|
+ margin-top: 16rpx;
|
|
|
+ width: 56rpx;
|
|
|
+ height: 56rpx;
|
|
|
+ border-radius: 50%;
|
|
|
+ border: 2rpx solid #fff;
|
|
|
+ color: #fff;
|
|
|
+ font-size: 34rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+}
|
|
|
+
|
|
|
+.popup-mask {
|
|
|
+ position: fixed;
|
|
|
+ inset: 0;
|
|
|
+ background: rgba(0, 0, 0, 0.45);
|
|
|
+ display: flex;
|
|
|
+ align-items: flex-end;
|
|
|
+ z-index: 99;
|
|
|
+}
|
|
|
+
|
|
|
+.popup-panel {
|
|
|
+ width: 100%;
|
|
|
+ height: 66vh;
|
|
|
+ background: #fff;
|
|
|
+ border-radius: 28rpx 28rpx 0 0;
|
|
|
+ padding: 24rpx;
|
|
|
+ box-sizing: border-box;
|
|
|
+}
|
|
|
+
|
|
|
+.popup-head {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+}
|
|
|
+
|
|
|
+.close-btn {
|
|
|
+ width: 54rpx;
|
|
|
+ height: 54rpx;
|
|
|
+ border-radius: 50%;
|
|
|
+ background: #f3f3f3;
|
|
|
+ color: #999;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ font-size: 28rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.popup-scroll {
|
|
|
+ height: calc(66vh - 90rpx);
|
|
|
+ margin-top: 16rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.popup-item {
|
|
|
+ background: #f5f5f5;
|
|
|
+ border-radius: 16rpx;
|
|
|
+ padding: 16rpx;
|
|
|
+ margin-bottom: 14rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.popup-item.active {
|
|
|
+ background: #ffeef1;
|
|
|
+}
|
|
|
+
|
|
|
+.popup-name {
|
|
|
+ margin-top: 8rpx;
|
|
|
+ font-family: PingFangSC, PingFang SC;
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 32rpx;
|
|
|
+ color: rgba(0,0,0,0.65);
|
|
|
+ line-height: 44rpx;
|
|
|
+}
|
|
|
+</style>
|