123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554 |
- <template>
- <view v-if="isVip">
- <view class="video_play" v-if="videoInfo.video_src">
- <video
- id="myVideo"
- class="video_control"
- @play="_videoPlay"
- :src="videoInfo.video_src"
- @timeupdate="timeUpdate"
- :enable-progress-gesture="false"
- :enable-play-gesture="true"
- :enable-auto-rotation="true"
- :initial-time="videoInfo.inittime || 0"
- :show-bottom-progress="videoInfo.learn_status == 1"
- @ended="_videoEnd"
- @fullscreenchange="screenChange"
- ></video>
- <cover-view v-if="videoInfo.learn_status == 0" :class="bigsScreen ? 'bigScreen' : 'cover'"></cover-view>
- </view>
- <view class="video_title">{{ videoInfo.name }}</view>
- <view class="rich_text">
- <rich-text :nodes="videoInfo.content"></rich-text>
- </view>
- <view class="contact_follow" v-if="videoInfo.service?.url">
- <button class="contact_btn" @click.stop="openCustomer()">
- <uni-icons type="headphones" size="30" color="#FFFFFF"></uni-icons>
- </button>
- </view>
- <uni-popup ref="questionRef" type="center" :is-mask-click="false">
- <view class="popup_content">
- <!-- 答题区域 -->
- <view class="content" v-if="!show_answer">
- <!-- 问题内容 -->
- <view class="question_content">{{ questinInfo.question_title }}</view>
- <!-- 问题选项 -->
- <view class="question_options">
- <view v-for="(option, index) in questinInfo.answer_list" :key="index" :class="['question_answer', { active: answer_id == option.id }]" @click="_selectAnswer(option.id)">
- {{ option.value }}
- </view>
- </view>
- <view :class="['submit_btn', { active: answer_id }]" @click="_submitAnswer">提交</view>
- </view>
- <!-- 结果区域 -->
- <view class="content" v-else>
- <icon :type="answerInfo.is_answer == 1 ? 'success' : 'cancel'" size="64" />
- <view class="title">{{ answerInfo.is_answer == 1 ? '恭喜您,答对啦!' : '很遗憾,答错了' }}</view>
- <view class="tip">{{ answerInfo.is_answer == 1 ? '继续保持,你正在进步!' : '别灰心,再接再厉!' }}</view>
- <view class="score_content">
- <view>得分</view>
- <view :style="answerInfo.get_score == 0 ? 'color:red' : 'color:green'">+{{ answerInfo.get_score }}</view>
- </view>
- <view class="submit_btn active" @click="_goPlayVedio">继续学习视频</view>
- </view>
- </view>
- </uni-popup>
- </view>
- <view v-else>
- <view class="not_vip">
- <image src="https://kailin-mp.oss-cn-shenzhen.aliyuncs.com/static/icon/is_no_vip.png" style="width: 300rpx; height: 252rpx" />
- <view class="content">
- <text>您还不是会员,暂时无法观看视频,请联系客服。</text>
- </view>
- </view>
- </view>
- </template>
- <script>
- export default {
- data() {
- return {
- videoInfo: {
- id: 0,
- name: '',
- content: '',
- video_src: '',
- },
- // 请求参数
- requestParam: {
- id: 0,
- },
- isReqing: false,
- videoContext: null,
- isAnswerQuestion: false,
- timer: null,
- currentTime: 0, // 新增变量用于存储当前播放时间
- questionTime_list: [],
- questinInfo: {},
- answer_id: null,
- is_correct: false,
- show_answer: false,
- answeredQuestions: new Set(), // 新增变量用于存储已回答的问题
- countdown: 0, // 新增变量用于存储倒计时时间
- bigsScreen: false,
- isVip: true,
- };
- },
- onLoad(param) {
- // 参数接收
- this.requestParam.id = param.id;
- // 如果存在产品ID的话
- if (this.requestParam.id > 0) {
- // 请求详情
- this.$http.request('api/video_course/get_detail', this.requestParam).then((re) => {
- // 成功渲染数据
- if (re.code == 'success') {
- // 刷新数据
- this.videoInfo = re.data;
- if (re.data.question_list) {
- this.questionTime_list = re.data?.question_list.map((item) => item.play_time);
- }
- // 获取视频容器的上下文
- this.videoContext = uni.createVideoContext('myVideo');
- // 暂停播放
- this.videoContext.stop();
- // #ifdef MP-WEIXIN
- uni.enableAlertBeforeUnload({
- message: '您确定要退出学习吗?',
- success: function (res) {
- console.log('方法注册成功:', res);
- },
- fail: function (errMsg) {
- console.log('方法注册失败:', errMsg);
- },
- });
- // #endif
- } else {
- if (re.code != 'no_login') {
- this.isVip = false;
- _isVip = false;
- // uni.showModal({
- // content: re.msg,
- // showCancel: false,
- // });
- }
- }
- });
- }
- // #ifdef MP-WEIXIN
- //分享按钮
- uni.showShareMenu({
- withShareTicket: true,
- menus: ['shareAppMessage', 'shareTimeline'],
- });
- // #endif
- },
- onUnload() {
- console.log('页面卸载');
- clearInterval(this.timer);
- },
- onShareAppMessage(obj) {
- return {
- title: `999智控终端平台\n${this.videoInfo.title}`,
- path: '/pages/video/detail?id=' + this.videoInfo.id,
- promise: new Promise((resolve, reject) => {
- this.$http
- .request('api/share_message/get_item', {
- item_id: this.videoInfo.id,
- pages: '/pages/video/detail',
- })
- .then((callback) => {
- console.log(callback, 'api/share_message/get_item');
- let obj = {
- title: callback.data?.title == '' ? `999智控终端平台\n${this.videoInfo.title}` : callback.data.title,
- path: '/pages/video/detail?id=' + this.videoInfo.id,
- };
- if (callback.data?.image_url !== '') {
- obj.imageUrl = callback.data.image_url;
- }
- resolve(obj);
- });
- }),
- };
- },
- onReady: function (res) {},
- onShow() {},
- methods: {
- openCustomer() {
- // #ifdef MP-WEIXIN
- console.log(1);
- wx.openCustomerServiceChat({
- extInfo: { url: this.videoInfo.service?.url },
- corpId: this.videoInfo.service?.corpid,
- success(res) {},
- });
- // #endif
- },
- timeUpdate(event) {
- this.currentTime = event.detail.currentTime; // 更新当前播放时间
- // 播放到对应的
- if (this.currentTime) {
- if (!this.timer) {
- this.timer = setInterval(() => {
- this._postVideoDuration(this.currentTime, 0);
- }, 3000);
- }
- if (this.currentTime == event.detail.duration) {
- this._postVideoDuration(this.currentTime, 1);
- }
- // 判断当前时间是否接近答题时间,并且该问题尚未回答
- if (this.questionTime_list.includes(parseInt(this.currentTime) + 3) && !this.answeredQuestions.has(parseInt(this.currentTime) + 3)) {
- this.countdown = 3;
- this._startCountdown();
- }
- if (this.questionTime_list.includes(parseInt(this.currentTime)) && !this.answeredQuestions.has(parseInt(this.currentTime))) {
- this.questinInfo = this.videoInfo.question_list.find((item) => item.play_time == parseInt(this.currentTime));
- this.videoContext.pause();
- this.videoContext.exitFullScreen();
- this.$refs.questionRef.open('center');
- //答题时间停止上报
- clearInterval(this.timer);
- this.timer = null;
- }
- }
- },
- _videoPlay() {
- console.log('开始播放');
- this.videoContext.requestFullScreen();
- },
- //上报视频播放时间
- _postVideoDuration(video_playtime, status) {
- if (status == 1) {
- clearInterval(this.timer);
- this.timer = null;
- }
- this.$http
- .request('api/video_learn_record/update_playtime', {
- record_id: this.videoInfo.record_id,
- video_playtime,
- status,
- })
- .then((re) => {
- if (re.code == 'success') {
- console.log('上报成功', video_playtime, status);
- }
- });
- },
- _selectAnswer(answer_id) {
- this.answer_id = answer_id;
- },
- _submitAnswer() {
- this.$http
- .request('api/video_learn_answer/play_exam', {
- record_id: this.videoInfo.record_id,
- course_id: this.questinInfo.course_id,
- question_id: this.questinInfo.question_id,
- answer_id: this.answer_id,
- })
- .then((re) => {
- if (re.code == 'success') {
- this.show_answer = true;
- this.answerInfo = re.data;
- // 将当前问题标记为已回答
- this.answeredQuestions.add(this.questinInfo.play_time);
- }
- });
- },
- _goPlayVedio() {
- this.questinInfo.isAnswer = true;
- this.show_answer = false;
- this.$refs.questionRef.close();
- uni.showToast({
- title: '2秒后切换横屏',
- icon: 'none',
- duration: 2000,
- });
- setTimeout(() => {
- this.videoContext.play();
- }, 2000);
- },
- _startCountdown() {
- const countdownInterval = setInterval(() => {
- if (this.countdown > 0) {
- uni.showToast({
- title: `${this.countdown}秒后进入答题`,
- icon: 'none',
- duration: 1000,
- });
- this.countdown--;
- } else {
- clearInterval(countdownInterval);
- }
- }, 1000);
- },
- _videoEnd() {
- const _this = this;
- this.videoContext.pause();
- this.videoContext.exitFullScreen();
- this._postVideoDuration(this.currentTime, 1);
- uni.showModal({
- title: '学习结束',
- content: '恭喜您学习结束,是否查看报告?',
- cancelText: '重新学习',
- success: (res) => {
- if (res.confirm) {
- uni.redirectTo({
- url: `/pages/video/record?type=learn&record_id=${this.videoInfo.record_id}`,
- });
- } else {
- //用户重新学习,将播放进度重新设为0
- setTimeout(() => {
- // 跳转到指定的时间位置
- _this.videoContext.seek(0);
- // _this.videoContext.play();
- }, 200);
- }
- },
- });
- },
- screenChange(event) {
- let fullScreen = event.detail.fullScreen;
- console.log('fullScreen', fullScreen);
- this.bigsScreen = fullScreen;
- },
- },
- };
- </script>
- <style lang="less">
- .video_play {
- width: 750rpx;
- display: block;
- font-size: 36rpx;
- overflow: hidden;
- font-weight: bold;
- line-height: 60rpx;
- background-color: #ffffff;
- position: relative;
- .video_control {
- width: 750rpx;
- display: block;
- font-size: 36rpx;
- overflow: hidden;
- font-weight: bold;
- line-height: 60rpx;
- background-color: #ffffff;
- }
- .cover {
- position: absolute;
- bottom: 0;
- z-index: 998;
- height: 20%;
- /* background-color: red; */
- background-color: rgba(255, 255, 255, 0.007);
- margin-left: 60px;
- width: 70%;
- }
- .bigScreen {
- position: absolute;
- bottom: -65%;
- z-index: 998;
- height: 20%;
- /* background-color: red; */
- background-color: rgba(255, 255, 255, 0.007);
- margin-left: 140px;
- width: 65%;
- }
- }
- .video_title {
- width: 700rpx;
- display: block;
- font-size: 36rpx;
- overflow: hidden;
- font-weight: bold;
- line-height: 60rpx;
- padding: 0rpx 25rpx;
- padding-top: 60rpx;
- background-color: #ffffff;
- }
- .video_time {
- width: 700rpx;
- color: #999999;
- display: block;
- font-size: 26rpx;
- overflow: hidden;
- line-height: 40rpx;
- padding: 0rpx 25rpx;
- background-color: #ffffff;
- }
- .rich_text {
- width: 700rpx;
- display: block;
- overflow: hidden;
- font-size: 26rpx;
- margin: 0rpx auto;
- min-height: 800rpx;
- line-height: 50rpx;
- padding: 10rpx 25rpx;
- background-color: #ffffff;
- [alt] {
- //web_view图片
- max-width: 100%; // 避免图片超宽
- vertical-align: bottom; // 避免图片之间间隙
- }
- }
- .video_poster {
- width: 700rpx;
- display: block;
- overflow: hidden;
- margin: 6rpx auto;
- padding: 10rpx 25rpx;
- background-color: #ffffff;
- .poster_img {
- width: 700rpx;
- display: block;
- }
- }
- .read_total {
- width: 700rpx;
- color: #999999;
- display: block;
- font-size: 26rpx;
- overflow: hidden;
- line-height: 60rpx;
- padding: 0rpx 25rpx;
- margin-bottom: 122rpx;
- background-color: #ffffff;
- }
- .handle_box {
- left: 0rpx;
- width: 700rpx;
- height: 120rpx;
- display: block;
- position: fixed;
- overflow: hidden;
- padding: 20rpx 25rpx;
- background-color: #ffffff;
- bottom: var(--window-bottom);
- border-top: 2rpx solid #dddddd;
- .click_box {
- border: none;
- float: right;
- display: block;
- height: 120rpx;
- padding: 0rpx 0rpx;
- line-height: 120rpx;
- margin-right: 20rpx;
- font-size: 24rpx !important;
- background-color: transparent;
- .uni-icons {
- font-size: 36rpx !important;
- }
- }
- .click_box::after {
- border: none;
- background-color: transparent;
- }
- }
- .popup_content {
- width: 600rpx;
- height: 800rpx;
- background-color: #ffffff;
- padding: 40rpx;
- border-radius: 10rpx;
- overflow: auto;
- .content {
- display: flex;
- flex-direction: column;
- gap: 20rpx;
- justify-content: space-around;
- height: 100%;
- align-items: center;
- .question_content {
- overflow-y: auto;
- font-size: 30rpx;
- font-weight: bold;
- }
- .question_options {
- display: flex;
- flex-direction: column;
- gap: 40rpx;
- width: 100%;
- .question_answer {
- height: 80rpx;
- width: 100%;
- border: 4rpx solid #e3e3e3;
- border-radius: 20rpx;
- display: flex;
- align-items: center;
- justify-content: center;
- &.active {
- border-color: #3c7aff;
- background-color: #dbeafe;
- }
- }
- }
- .submit_btn {
- width: 100%;
- display: flex;
- align-items: center;
- justify-content: center;
- color: #fff;
- height: 100rpx;
- background-color: #dddddd;
- border-radius: 20rpx;
- &.active {
- background-color: #5045e6;
- }
- }
- .title {
- font-size: 64rpx;
- font-weight: bold;
- }
- .score_content {
- background-color: #f3f5f7;
- padding: 40rpx;
- display: flex;
- align-items: center;
- justify-content: space-between;
- width: 100%;
- border-radius: 20rpx;
- box-sizing: border-box;
- }
- }
- }
- .contact_follow {
- bottom: 30%;
- right: 20rpx;
- width: 100rpx;
- height: 100rpx;
- display: block;
- position: fixed;
- border-radius: 50%;
- background-color: #1296db;
- .contact_btn {
- border: none;
- width: 100rpx;
- color: #ffffff;
- height: 100rpx;
- padding: 0rpx 0rpx;
- line-height: 100rpx;
- text-align: center;
- border-radius: 50%;
- background-color: #1296db;
- }
- .contact_btn::after {
- border: none;
- }
- }
- .not_vip {
- background-color: #ddd;
- width: 100vw;
- height: 100vh;
- display: flex;
- align-items: center;
- flex-direction: column;
- justify-content: center;
- .content {
- width: 70%;
- margin-top: 20rpx;
- text-align: center;
- }
- }
- </style>
|