Files
gym-manage/gym-manage-uniapp/pages/memberInfo/onlineCourseDetail.vue
T
2026-06-11 14:26:49 +08:00

120 lines
4.9 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.
<template>
<view class="scroll-container theme-light">
<view class="bt-page" v-if="course">
<MemberInfoSubNav title="线上课程" @back="onBack" />
<image class="mi-detail-hero" :src="course.cover" mode="aspectFill" />
<view class="bt-page__body">
<view class="bt-card">
<text class="bt-card__title">{{ course.title }}</text>
<text class="bt-card__desc">时长 {{ course.duration }} · 进度 {{ course.progress }}%</text>
<view class="mi-mod-course-card__progress" style="margin-top:12px;">
<view class="mi-mod-course-card__progress-bar">
<view class="mi-mod-course-card__progress-fill" :style="{ width: course.progress + '%' }"></view>
</view>
</view>
</view>
<view class="bt-card">
<text class="bt-card__title">视频播放</text>
<view class="mi-online-player">
<image class="mi-online-player__play" src="/static/images/play.png" mode="aspectFit" />
<text class="mi-online-player__hint">点击播放支持倍速与拖拽</text>
</view>
<view class="mi-online-controls">
<text class="mi-online-controls__btn" @tap="seek(-10)">-10s</text>
<text class="mi-online-controls__btn" @tap="togglePlay">{{ playing ? '暂停' : '播放' }}</text>
<text class="mi-online-controls__btn" @tap="seek(10)">+10s</text>
<text class="mi-online-controls__btn" @tap="changeSpeed">倍速 {{ speed }}x</text>
</view>
</view>
<view class="bt-card">
<text class="bt-card__title">课程目录</text>
<view v-for="ch in course.chapters" :key="ch.id" class="mi-online-chapter">
<text class="mi-online-chapter__title">{{ ch.title }}</text>
<text class="mi-online-chapter__meta">{{ ch.duration }} · {{ ch.done ? '已学完' : '未学习' }}</text>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import MemberInfoSubNav from '@/components/memberInfo/MemberInfoSubNav.vue'
import { PAGE, goBackOrTab } from '@/common/constants/routes.js'
import { loadMemberStore, persistMemberStore } from '@/common/memberInfo/store.js'
import { getOnlineCourseById, updateOnlineProgress } from '@/common/memberInfo/moduleStore.js'
export default {
components: { MemberInfoSubNav },
data() {
return { course: null, playing: false, speed: 1 }
},
onLoad(options) {
this.course = getOnlineCourseById(loadMemberStore(), options?.id)
},
methods: {
onBack() { goBackOrTab(PAGE.MY_COURSES) },
togglePlay() {
this.playing = !this.playing
if (this.playing && this.course.progress < 100) {
const store = loadMemberStore()
updateOnlineProgress(store, this.course.id, Math.min(100, this.course.progress + 5))
persistMemberStore(store)
this.course.progress = Math.min(100, this.course.progress + 5)
}
},
seek(sec) { uni.showToast({ title: `跳转 ${sec > 0 ? '+' : ''}${sec}s`, icon: 'none' }) },
changeSpeed() {
const speeds = [1, 1.25, 1.5, 2]
const idx = (speeds.indexOf(this.speed) + 1) % speeds.length
this.speed = speeds[idx]
}
}
}
</script>
<style>
@import '@/common/style/base.css';
@import '@/common/style/memberInfo/pages/page-reset.css';
@import '@/common/style/memberInfo/pages/sub-page-base.css';
@import '@/common/style/memberInfo/member-info-component-reset.css';
@import '@/common/style/memberInfo/member-info-sub-nav.css';
@import '@/common/style/memberInfo/pages/body-test-common.css';
@import '@/common/style/memberInfo/pages/module-pages-common.css';
.mi-online-player {
height: 180px;
border-radius: 12px;
background: #000;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 8px;
}
.mi-online-player__play { width: 48px; height: 48px; }
.mi-online-player__hint { font-size: 12px; color: rgba(255,255,255,0.7); }
.mi-online-controls {
display: flex;
flex-direction: row;
justify-content: space-around;
margin-top: 12px;
}
.mi-online-controls__btn {
font-size: 12px;
color: var(--primary-deep, #1A4A6F);
font-weight: 600;
}
.mi-online-chapter {
padding: 10px 0;
border-bottom: 1px solid var(--border-light, #E9EDF2);
}
.mi-online-chapter__title { font-size: 14px; color: var(--text-dark, #1E2A3A); display: block; }
.mi-online-chapter__meta { font-size: 11px; color: var(--text-muted, #5E6F8D); }
</style>