wangxy hai 2 meses
pai
achega
e36e1e0b38

+ 9 - 2
components/kecheng-mulu/kecheng-mulu.vue

@@ -4,10 +4,14 @@
 			:open="zhang.open">
 			<myCollapseCardVue v-for="jie in zhang.jieList" :title="jie.name" @click.stop="handleJieClick(jie, zhang)"
 				:open="jie.open">
-				<view class="kejian-item" v-for="item in jie.kejianList" @click.stop="handleKejianClick(item)">
+				<view :class="{'kejian-active': activeKjId == item.kjId,'kejian-item':true }" v-for="item in jie.kejianList" @click.stop="handleKejianClick(item)">
 					<icon class="kejian-item-icon"></icon>
 					<text>{{item.name}}</text>
-					<text v-if="isHasProgress">进度{{item.curProcess}}</text>
+					<text v-if="isHasProgress">
+						进度
+						<text v-if="item.maxProcess < 100" v-text="item.maxProcess >= item.curProcess ? item.maxProcess: item.curProcess"></text>
+						<text v-else v-text="item.maxProcess"></text>
+					</text>
 				</view>
 			</myCollapseCardVue>
 		</myCollapseCardVue>
@@ -25,6 +29,9 @@
 		},
 		isHasProgress: {
 			type: Boolean
+		},
+		activeKjId: {
+			type: [Number,String]
 		}
 	})
 

+ 4 - 3
components/listCard/kechengCard.vue

@@ -16,20 +16,21 @@
 				<icon class="card-time-icon"></icon>
 				<view class="content-text-box">
 					<text>时间</text>
-					<view>{{data.totalTm}}分钟</view>
+					<view>{{formatSecondsToCnhms(data.period, true)}}</view>
 				</view>
 			</view>
 		</view>
 		<!-- 底部 -->
 		<view class="card-bottom-box">
 			<button type="default" class="index-card-btn" v-if="data.status == 1">课程学习</button>
-			<button type="default" class="index-card-btn" v-if="data.status == 2">学习中</button>
-			<button type="default" class="index-card-btn" v-if="data.status == 3">已完成</button>
+			<button type="default" class="index-card-btn" v-if="data.status == 3">学习中</button>
+			<button type="default" class="index-card-btn" v-if="data.status == 2">已完成</button>
 		</view>
 	</view>
 </template>
 
 <script setup>
+	import {formatSecondsToCnhms} from "@/utils/common.js"
 	defineProps({
 		data: {
 			type: Object,

+ 1 - 2
components/listCard/lianxiCard.vue

@@ -36,8 +36,7 @@
 		</view>
 		<!-- 底部 -->
 		<view class="card-bottom-box">
-			<button type="default" class="index-card-btn" @click="handleStart(data)" v-if="data.status == 1">进行考试</button>
-			<button type="default" class="index-card-btn" @click="handleStart(data)" v-if="data.status == 2">再次考试</button>
+			<button type="default" class="index-card-btn" @click="handleStart(data)">进行考试</button>
 		</view>
 		
 		<!-- 考试须知 -->

+ 1 - 1
components/myCollapseCard/myCollapseCard.vue

@@ -1,7 +1,7 @@
 <template>
 	<view class="my-collapse-card">
 		<view class="my-collapse-item" :class="{'item-open': open}">
-			<text class="collapse-text">{{title}} --- {{open}}</text>
+			<text class="collapse-text">{{title}}</text>
 			<icon class="collapse-item-icon"></icon>
 		</view>
 		<view class="my-card-content" :class="{'content-open': open}">

+ 39 - 2
components/videoPlay/videoPlay.vue

@@ -1,7 +1,9 @@
 <template>
 	<view>
 		<view ref="videoContent" id="wgy-player-test" :playAuth="playAuth" :change:playAuth="renderScript.receiveMsg"
-			:videoId="videoId" :change:videoId="renderScript.videoIdFun" :status="hideFlag"
+			:videoId="videoId" :change:videoId="renderScript.videoIdFun" 
+			:playCount="playCount" :change:playCount="renderScript.playVideo"
+			:status="hideFlag"
 			:change:hideFlag="renderScript.hideFlagFun" :seekTime="seekTime" :change:seekTime="renderScript.seekTimeFun"
 			class="kecheng-video">
 		</view>
@@ -17,6 +19,7 @@
 				hideFlag: 'show',
 				videoId: "", //阿里云视频id
 				seekTime: '',
+				playCount: 0,
 			};
 		},
 		onUnload() {
@@ -31,6 +34,10 @@
 				this.playAuth = options.playAuth;
 				this.videoId = options.videoId;
 				this.seekTime = options.seekTime;
+				const isPlay = options.isPlay || false;
+				if(isPlay) {
+					this.playCount++
+				}
 			},
 			setSeekTime(seekTime) {
 				this.seekTime = '';
@@ -38,6 +45,18 @@
 					this.seekTime = seekTime;
 				})
 			},
+			handlePause() {
+				this.$emit('play-pause')
+			},
+			handlePlay() {
+				this.$emit('play-play')
+			},
+			playEnd() {
+				this.$emit('play-end')
+			},
+			handleTimeupdate(timer) {
+				this.$emit('play-timeupdate',timer)
+			}
 		}
 	}
 </script>
@@ -52,6 +71,11 @@
 			}
 		},
 		methods: {
+			playVideo() {
+				setTimeout(() => {
+					this.player && this.player.play()
+				}, 300);
+			},
 			receiveMsg(newValue, oldValue, ownerInstance, instance) {
 				if (newValue) {
 					this.playAuth = ''
@@ -142,7 +166,9 @@
 					controlBarVisibility: "hover",
 					useH5Prism: true
 
-				}, function(player) {});
+				}, function(player) {
+					console.log('ppp', player)
+				});
 				this.player = player;
 				player.on('canplay', function() {
 					player.tag.play();
@@ -152,6 +178,17 @@
 						data: 'end'
 					})
 				});
+				player.on('pause', function() {
+					that.$ownerInstance.callMethod('handlePause')
+				});
+				player.on('play', function() {
+					that.$ownerInstance.callMethod('handlePlay')
+				});
+				player.on('timeupdate', function(time) {
+					that.$ownerInstance.callMethod('handleTimeupdate',time.target.childNodes[0].currentTime)
+				});
+				
+				
 			},
 			isHasScript() {
 				let scriptExists = false;

+ 7 - 0
pages.json

@@ -147,6 +147,13 @@
 			"style": {
 				"navigationStyle": "custom"
 			}
+		},
+		{
+			"path" : "pages/client/Kecheng/study",
+			"style" : 
+			{
+				"navigationStyle": "custom"
+			}
 		}
 	],
 	"tabBar": {

+ 6 - 8
pages/admin/Kecheng/study.vue

@@ -18,7 +18,7 @@
 		</view>
 		<view class="kecheng-content-box">
 			<!-- 目录 -->
-			<kechengMuluVue v-if="current === 0" :chapterArr="list" @play="handlePlay" :isHasProgress="false"></kechengMuluVue>
+			<kechengMuluVue v-if="current === 0" :chapterArr="list" @play="handlePlay" :isHasProgress="false" :activeKjId="curPlayData&&curPlayData.kjId"></kechengMuluVue>
 			<!-- 介绍 -->
 			<rich-text :nodes="intro" v-if="current === 1 && intro" class="kecheng-jieshao-box"></rich-text>
 		</view>
@@ -84,16 +84,10 @@
 				if (this.curPlayData && this.curPlayData.videoId == data.videoId) {
 					return;
 				}
-
-				// console.log('播放进度', data)
+				this.curPlayData = data;
 				kechengApi.getVideoAuth({
 					videoId: data.url
 				}).then(res => {
-					// console.log('切换视频', {
-					// 	videoId: data.url,
-					// 	playAuth: res.data,
-					// 	seekTime: '',
-					// });
 					this.$refs.videoRef.init({
 						videoId: data.url,
 						playAuth: res.data,
@@ -103,6 +97,10 @@
 			},
 			initFirstVideo() {
 				if (this.list && this.list[0].jieList && this.list[0].jieList[0].kejianList) {
+					// 设置默认展开项
+					this.list[0].open = true;
+					this.list[0].jieList[0].open = true;
+					
 					const kejian = this.list[0].jieList[0].kejianList[0];
 					this.handlePlay(kejian)
 				}

+ 4 - 3
pages/client/Kecheng/list.vue

@@ -19,7 +19,7 @@
 									<view class="ks-zyLevelName">{{item.zyLevelName}}</view>
 								</view>
 								<view class="ks-totalTm">
-									<icon class="phone-time-icon" />时间:{{formatDuration(item.period)}}分钟
+									<icon class="phone-time-icon" />时间:{{formatSecondsToCnhms(item.period, true)}}
 								</view>
 								<button @click="checkKecheng(item)" type="primary" size="mini"  class="kaoshi-btn">查看内容</button>
 							</view>
@@ -32,12 +32,13 @@
 		</view>
 
 		<!-- 页面底端 -->
-		<customTabbarAdminVue></customTabbarAdminVue>
+		<customTabbarClientVue></customTabbarClientVue>
 	</view>
 </template>
 
 <script setup>
 	import customTabbarClientVue from "@/components/custom-tabbar/custom-tabbar-client.vue";
+
 	import {
 		ref,
 		reactive
@@ -46,7 +47,7 @@
 		onLoad
 	} from "@dcloudio/uni-app";
 	import * as kechengApi from "@/api/kecheng.js"
-	import {formatDuration} from "@/utils/common.js"
+	import {formatSecondsToCnhms} from "@/utils/common.js"
 
 	const data = reactive({
 		zyName: '', // 职业名称

+ 269 - 0
pages/client/Kecheng/study.vue

@@ -0,0 +1,269 @@
+<template>
+	<view class="kecheng-study-page">
+		<view class="icon-title-navBar-box">
+			<view @click="goUpPage" class="nav-bar-icon"></view>
+			<text class="nav-bar-title">{{name}}</text>
+		</view>
+		<!-- 播放器 -->
+		<videoPlayVue ref="videoRef" class="phone-video-box" @play-end="onPlayEnd" @play-play="onPlay"
+			@play-pause="onPause" @play-timeupdate="onTimeupdate"></videoPlayVue>
+		<!-- 中间区域 -->
+		<view class="kc-info-box">
+			<view>时长:{{period}}分钟</view>
+			<view>{{userCount}}人学习</view>
+		</view>
+		<!-- 大纲 -->
+		<view class="phone-tab-box">
+			<uni-segmented-control :current="current" :values="items" style-type="text" :active-color="activeColor"
+				@clickItem="onClickItem" />
+		</view>
+		<view class="kecheng-content-box">
+			<!-- 目录 -->
+			<kechengMuluVue v-if="current === 0" :chapterArr="list" @play="handlePlay" :isHasProgress="true"
+				:activeKjId="curPlayData&&curPlayData.kjId"></kechengMuluVue>
+			<!-- 介绍 -->
+			<rich-text :nodes="intro || '暂无内容'" v-if="current === 1 && intro" class="kecheng-jieshao-box"></rich-text>
+		</view>
+	</view>
+</template>
+
+<script>
+	import * as kechengApi from "@/api/kecheng.js";
+	import videoPlayVue from "@/components/videoPlay/videoPlay.vue";
+	import kechengMuluVue from "@/components/kecheng-mulu/kecheng-mulu.vue";
+	import {
+		useUserCache
+	} from "@/utils/userCache.js"
+	import {
+		formatDuration
+	} from "@/utils/common.js"
+	import {
+		useKechengTools
+	} from "./useKechengCache.js"
+
+	const {
+		getCurKjIndex,
+		saveKechengData,
+		getKechengDataFromHistory,
+		saveKechengSectionPage,
+		getKechengSectionPageFromHistory,
+		mergeProgress,
+		initCourseProgressAll,
+		saveCourseProgress,
+		getCourseProgress,
+		updateSectionProgress,
+		saveInterfaceAbnormal
+	} = useKechengTools();
+
+	export default {
+		components: {
+			videoPlayVue,
+			kechengMuluVue
+		},
+		data() {
+			return {
+				items: ['目录', '介绍'],
+				colors: ['#007aff', '#4cd964', '#dd524d'],
+				activeColor: '#3fd2a1',
+				current: 0, // 激活的选项卡
+				operId: '', // 课程
+				name: '',
+				period: 0, // 时长
+				userCount: 0, // 学习人数
+				list: [],
+				intro: '',
+				curPlayData: null,
+				timer1: null,
+				kcId: null,
+			}
+		},
+		onLoad(options) {
+			this.kcId = options.kcId;
+			this.init();
+		},
+		methods: {
+			onPause() {
+				clearInterval(this.timer1);
+				this.timer1 = null;
+			},
+			onPlay() {
+				clearInterval(this.timer1);
+				this.timer1 = null;
+				this.timer = setInterval(() => {
+					updateSectionProgress(this.operId);
+				}, 1000 * 5 * 60)
+			
+			},
+			sectionPlayerProgress(progress) {
+				let sectionPage = getKechengSectionPageFromHistory(this.operId);
+				console.log('sectionPage',sectionPage)
+				let maxProcess = this.list[sectionPage.iChapter].jieList[sectionPage.iSection].kejianList.find(it1=>it1.kjId == sectionPage.kjId).maxProcess;
+				// 更新缓存进度
+				this.list[sectionPage.iChapter].jieList[sectionPage.iSection].kejianList.find(it1=>it1.kjId == sectionPage.kjId).curProcess = progress;
+				if (progress < 100) {
+					// 播放进度小于100
+					if (progress < maxProcess) {
+						this.list[sectionPage.iChapter].jieList[sectionPage.iSection].kejianList.find(it1=>it1.kjId == sectionPage.kjId).maxProcess = maxProcess
+					} else {
+						this.list[sectionPage.iChapter].jieList[sectionPage.iSection].kejianList.find(it1=>it1.kjId == sectionPage.kjId).maxProcess = progress
+					}
+				} else {
+					// 播放进度大于100
+					this.list[sectionPage.iChapter].jieList[sectionPage.iSection].kejianList.find(it1=>it1.kjId == sectionPage.kjId).maxProcess = 100
+				}
+			},
+			onTimeupdate(time) {
+				const progress = parseInt(time / this.curPlayData.duration * 100);
+				this.curPlayData.curProgress = parseInt(progress >= 100 ? '99' : progress);
+				// 保存进度
+				saveCourseProgress(time, this.curPlayData.duration, this.operId)
+				// 更新进度
+				this.sectionPlayerProgress(progress)
+			},
+			onPlayEnd() {
+				clearInterval(this.timer1);
+				this.timer1 = null;
+				saveCourseProgress(this.curPlayData.duration, this.curPlayData.duration, this.operId, 'end');
+				updateSectionProgress(this.operId, 'end', 'video', () => {
+					this.curPlayData.maxProcess = 99;
+					this.curPlayData.curProcess = 99;
+				});
+				console.log('end')
+			},
+			goUpPage() {
+				uni.redirectTo({
+					url: '/pages/admin/Kecheng/list'
+				})
+			},
+			onClickItem(e) {
+				if (this.current !== e.currentIndex) {
+					this.current = e.currentIndex
+				}
+			},
+			formatData(data) {
+				data.forEach(zhang => {
+					zhang.open = false;
+					zhang.jieList.forEach(jie => {
+						jie.open = false;
+					})
+				})
+				return data;
+			},
+			handlePlay(data) {
+				if (this.curPlayData && this.curPlayData.url == data.url) {
+					return;
+				}
+				this.curPlayData = data;
+				
+				const {
+					zhangIndex,
+					jieIndex
+				} = getCurKjIndex(data.kjId,this.operId)
+				const sectionPage = {};
+				sectionPage.iChapter = zhangIndex;
+				sectionPage.iSection = jieIndex;
+				sectionPage.kjId = data.kjId;
+				sectionPage.operId = this.operId;
+				saveKechengSectionPage(this.operId, sectionPage)
+				
+				kechengApi.getVideoAuth({
+					videoId: data.url
+				}).then(res => {
+					this.$refs.videoRef.init({
+						videoId: data.url,
+						playAuth: res.data,
+						seekTime: '',
+						isPlay: true
+					})
+
+				})
+			},
+			initFirstVideo() {
+				let sectionPage = getKechengSectionPageFromHistory(this.operId)
+				if (sectionPage) {
+					const {
+						zhangIndex,
+						jieIndex
+					} = getCurKjIndex(sectionPage.kjId,this.operId)
+					sectionPage.iChapter = zhangIndex;
+					sectionPage.iSection = jieIndex;
+					sectionPage.kjId = sectionPage.kjId;
+					sectionPage.operId = this.operId;
+					
+					// 设置默认展开项
+					this.list[zhangIndex].open = true;
+					this.list[zhangIndex].jieList[jieIndex].open = true;
+					
+					const kejian = this.list[0].jieList && this.list[zhangIndex].jieList[jieIndex].kejianList.find(item => item.kjId ==sectionPage.kjId )
+					this.handlePlay(kejian)
+				} else {
+					if (this.list && this.list[0].jieList && this.list[0].jieList[0].kejianList) {
+						// 设置默认展开项
+						this.list[0].open = true;
+						this.list[0].jieList[0].open = true;
+						// 设置播放可见
+						const kejian = this.list[0].jieList[0].kejianList[0];
+						this.handlePlay(kejian)
+						// 更新缓存
+						sectionPage = {
+							kjId: kejian.kjId,
+							iChapter: 0,
+							iSection: 0,
+							operId: this.operId
+						}
+					}
+				}
+		
+				saveKechengSectionPage(this.operId, sectionPage)
+			},
+
+			init() {
+				kechengApi.getClientKechengStart({
+					kcId: this.kcId
+				}).then(res => {
+					const {
+						userCount,
+						period,
+						name,
+						kejianUserVo,
+						intro,
+						operId
+					} = res.data;
+					this.userCount = userCount;
+					this.period = formatDuration(period);
+					this.name = name;
+					this.formatData(kejianUserVo.zhangList)
+					this.list = kejianUserVo.zhangList;
+					this.intro = intro;
+					this.operId = operId;
+
+					// 获取课程缓存 && 课件缓存(课件缓存点击后产生)
+					let historyArrKecheng = getKechengDataFromHistory(this.operId)
+					let sectionPageHistory = getKechengSectionPageFromHistory(this.operId)
+					// 判断是否有前台缓存
+					if (historyArrKecheng && sectionPageHistory) {
+						// 有缓存---- 把start接口中,返回数据进度100%,更新到前台缓存
+						const arrKecheng = mergeProgress(kejianUserVo && kejianUserVo.zhangList,
+							historyArrKecheng);
+						// 后台数据 同步前台缓存
+						saveKechengData(this.operId, arrKecheng)
+					} else {
+						// 无缓存----把start接口中,返回的所有数据,更新到前台缓存
+						saveKechengData(this.operId, kejianUserVo && kejianUserVo.zhangList)
+					}
+					// 初始化页面 常规数据
+					initCourseProgressAll(this.operId)
+
+					console.log('初始化播放首次')
+					// 设置播放视频
+					this.initFirstVideo();
+				})
+			}
+		}
+	}
+</script>
+
+
+<style>
+
+</style>

+ 246 - 0
pages/client/Kecheng/useKechengCache.js

@@ -0,0 +1,246 @@
+import {
+	useUserCache
+} from "@/utils/userCache.js"
+import * as kcApi from "@/api/kecheng.js"
+
+export function useKechengTools() {
+	const {
+		saveCache,
+		getCache,
+		removeCache
+	} = useUserCache();
+
+	function getCurKjIndex(kjId, operId) {
+		const arrKecheng = getKechengDataFromHistory(operId);
+		for (let zi = 0; zi < arrKecheng.length; zi++) {
+			for (let ji = 0; ji < arrKecheng[zi].jieList.length; ji++) {
+				if (arrKecheng[zi].jieList[ji].kejianList.some(kj => kj.kjId == kjId)) {
+					return {
+						zhangIndex: zi,
+						jieIndex: ji
+					}
+				}
+			}
+		}
+	}
+
+	function mergeProgress(backData, historyData) {
+		const curData = JSON.parse(JSON.stringify(historyData));
+		backData.forEach((item, zhangIndex) => {
+			item.jieList.forEach((jieItem, jieIndex) => {
+				jieItem.kejianList.forEach((kjItem, kjIndex) => {
+					const backCurJie = backData[zhangIndex].jieList[jieIndex].kejianList[
+						kjIndex];
+
+					// 大于等于100 的进度以后台为准
+					if (kjItem.maxProcess >= 100) {
+						curData[zhangIndex].jieList[jieIndex].kejianList[kjIndex] = backCurJie;
+					} else if (curData[zhangIndex].jieList[jieIndex].kejianList[kjIndex]
+						.maxProcess == 100) {
+						// 前台缓存进度为100 使用后台进度
+						//   alert('前台缓存进度为100 使用后台进度')
+						curData[zhangIndex].jieList[jieIndex].kejianList[kjIndex] = backCurJie;
+					}
+					curData[zhangIndex].jieList[jieIndex].kejianList[kjIndex].lockFlag =
+						backCurJie.lockFlag;
+				})
+			})
+		})
+		return curData;
+	}
+
+	function saveKechengData(operId, data) {
+		saveCache('SectionInfo' + operId, 'arrKecheng', data)
+	}
+
+	function getKechengDataFromHistory(operId) {
+		return getCache('SectionInfo' + operId, 'arrKecheng')
+	}
+
+	function saveKechengSectionPage(operId, data) {
+		saveCache('SectionInfo' + operId, 'sectionPage', data)
+	}
+
+	function getKechengSectionPageFromHistory(operId) {
+		return getCache('SectionInfo' + operId, 'sectionPage')
+	}
+
+	function initCourseProgressAll(operId) {
+		let arrKecheng = getCache('SectionInfo' + operId, 'arrKecheng');
+		// 判断是否有课程信息
+		if (!arrKecheng || arrKecheng.length === 0) {
+			throw new Error('initCourseProgress业务逻辑错误: arrKecheng 异常');
+		}
+
+		for (const chapter of arrKecheng) {
+			for (const section of chapter.jieList) {
+				let kejianArr = section.kejianList;
+				if (kejianArr && kejianArr.length > 0) {
+					for (const kejian of kejianArr) {
+						if (!kejian.maxProcess) {
+							kejian.curProcess = 0;
+							kejian.maxProcess = 0;
+							kejian.hasFinished = false;
+						} else if (kejian.maxProcess < 100) {
+							kejian.hasFinished = false;
+						}
+					}
+				}
+			}
+		}
+		saveCache('SectionInfo' + operId, 'arrKecheng', arrKecheng);
+		return arrKecheng;
+	}
+
+	function saveCourseProgress(cur, total, operId, code, type) {
+		let sectionPage = getCache('SectionInfo' + operId, 'sectionPage');
+		let arrKecheng = getCache('SectionInfo' + operId, 'arrKecheng');
+		
+		let section = arrKecheng[sectionPage.iChapter].jieList[sectionPage.iSection];
+
+		for (const kejian of section.kejianList) {
+			if (kejian.kjId === sectionPage.kjId) {
+				// video或audio的end为100,其他情况最大99
+				if (code === 'end') {
+					kejian['curProcess'] = 100;
+					kejian['maxProcess'] = 100;
+				} else if (type === 'other') {
+					// 除了音视频以外的课件
+					kejian['curProcess'] = 100;
+					kejian['maxProcess'] = 100;
+				} else {
+					// 0 ~ 99
+					kejian['curProcess'] = parseInt(cur / total * 100) >= 100 ?
+						99 :
+						parseInt(cur / total * 100);
+
+					kejian['maxProcess'] = kejian['curProcess'] > kejian['maxProcess'] ?
+						kejian['curProcess'] :
+						kejian['maxProcess'];
+				}
+				break;
+			}
+		}
+
+		saveCache('SectionInfo' + operId, 'arrKecheng', arrKecheng);
+	}
+
+	function getCourseProgress(total) {
+		let sectionPage = getCache('SectionInfo', 'sectionPage');
+		let arrKecheng = getCache('SectionInfo', 'arrKecheng');
+		let section = getSection(arrKecheng, sectionPage.iChapter, sectionPage.iSection);
+
+		for (const kejian of section.kejianList) {
+			if (kejian.kjId === sectionPage.kjId) {
+				return {
+					cur: total * parseFloat(kejian['curProcess']) / 100,
+					max: total * parseFloat(kejian['maxProcess']) / 100,
+				};
+			}
+		}
+	}
+
+	function updateSectionProgress(operId, code, type, callback) {
+
+		let sectionPage = getCache('SectionInfo' + operId, 'sectionPage');
+		let arrKecheng = getCache('SectionInfo' + operId, 'arrKecheng');
+
+		if (sectionPage && sectionPage.finish) {
+			console.log('已经结束,不再保存进度')
+			return;
+		}
+
+		let kejianList = arrKecheng[sectionPage.iChapter].jieList[sectionPage.iSection].kejianList;
+		let kejianIndex = kejianList.findIndex(item => item.kjId === sectionPage.kjId);
+
+		const optX = {
+			zhangIndex: sectionPage.iChapter,
+			jieIndex: sectionPage.iSection,
+			kejianIndex: kejianIndex,
+			kjId: sectionPage.kjId,
+			operId: sectionPage.operId,
+			process: kejianList[kejianIndex].maxProcess,
+			customLoadingSwitch: false,
+		};
+
+		saveCache('SectionInfo' + operId, 'arrKecheng', arrKecheng);
+		const saveOpt = {
+			kejianList: kejianList,
+			kejianIndex: kejianIndex,
+			arrKecheng: arrKecheng,
+			optX: optX,
+		};
+		// 音视频end
+		if (code === 'end') {
+			kcApi.getClientKechengSave(optX).then(res => {
+				// 接口正常执行
+				if (res.code === 0) {
+					// 音视频end事件
+					kejianList[kejianIndex].curProcess = 100;
+					kejianList[kejianIndex].maxProcess = 100;
+					arrKecheng[optX.zhangIndex].jieList[optX.jieIndex].kejianList[optX.kejianIndex]
+						.hasFinished = true;
+					saveCache('SectionInfo' + operId, 'arrKecheng', arrKecheng);
+					if (res.data.finish === true) {
+						// 整个课程学完 data为true
+						uni.showToast({
+							title: "课程已学完!"
+						})
+						sectionPage.finish = true;
+						saveCache('SectionInfo' + operId, 'sectionPage', sectionPage);
+					}
+				} else {
+					saveInterfaceAbnormal(saveOpt, 99);
+					callback(99)
+				}
+			}).catch(err => {
+				saveInterfaceAbnormal(saveOpt, 99);
+				callback(99)
+			});
+		} else {
+			// 其他情况(音视频一秒一保存)
+			getTskcSave(optX).then(res => {
+				if (res.code === 0) {
+					if (res.data.finish === true) {
+						uni.showToast({
+							title: "课程已学完!"
+						})
+						sectionPage.finish = true;
+						saveCache('SectionInfo' + operId, 'sectionPage', sectionPage);
+					}
+				}
+			});
+		}
+	}
+
+	function saveInterfaceAbnormal(saveOpt, jindu) {
+		const {
+			kejianList,
+			kejianIndex,
+			arrKecheng,
+			optX,
+			operId
+		} = saveOpt;
+		kejianList[kejianIndex].curProcess = jindu;
+		kejianList[kejianIndex].maxProcess = jindu;
+		arrKecheng[optX.zhangIndex].jieList[optX.jieIndex].kejianList[optX.kejianIndex].hasFinished = false;
+		saveCache('SectionInfo' + operId, 'arrKecheng', arrKecheng);
+		uni.redirectTo({
+			url:"/pages/client/Kecheng/list"
+		})
+	}
+
+	return {
+		getCurKjIndex,
+		saveKechengData,
+		getKechengDataFromHistory,
+		saveKechengSectionPage,
+		getKechengSectionPageFromHistory,
+		mergeProgress,
+		initCourseProgressAll,
+		saveCourseProgress,
+		getCourseProgress,
+		updateSectionProgress,
+		saveInterfaceAbnormal
+	}
+}

+ 7 - 7
pages/client/my/myInfo.vue

@@ -151,13 +151,13 @@
 	}
 
 	function handleUpdate() {
-		myApi.getUserUpdate({}).then(res => {
-			if (res.data) {
-				uni.showToast({
-					title: '更新成功'
-				})
-			}
-		})
+		// myApi.getUserUpdate({}).then(res => {
+		// 	if (res.data) {
+		// 		uni.showToast({
+		// 			title: '更新成功'
+		// 		})
+		// 	}
+		// })
 	}
 
 	function handleBack() {

+ 41 - 0
utils/common.js

@@ -85,3 +85,44 @@ export function getStaticUrl(url) {
 	return result;
 }
 	
+export function formatSecondsToCnhms(value, isNoZero) {
+    if (!value || value == 0) {
+        return '';
+    }
+    let result = parseInt(value);
+    let h = isNoZero ? Math.floor(result / 3600) : Math.floor(result / 3600) < 10
+        ? '0' + Math.floor(result / 3600)
+        : Math.floor(result / 3600);
+    let m = isNoZero ? Math.floor((result / 60 % 60)) : Math.floor((result / 60 % 60)) < 10
+        ? '0' + Math.floor((result / 60 % 60))
+        : Math.floor((result / 60 % 60));
+    let s = isNoZero ? Math.floor((result % 60)) : Math.floor((result % 60)) < 10
+        ? '0' + Math.floor((result % 60))
+        : Math.floor((result % 60));
+    if (isNoZero) {
+        result = '';
+        if (h !== 0) {
+            result += `${h}时`;
+            // 判断如果有时有秒,分钟为0也显示
+            if (s !== 0) {
+                // 分为零也显示
+                if (m === 0) {
+                    result += `${m}分`;
+                }
+
+            }
+
+        }
+        // 分钟不为零显示
+        if (m !== 0) {
+            result += `${m}分`;
+        }
+        // 秒不为零显示
+        if (s !== 0) {
+            result += `${s}秒`;
+        }
+    } else {
+        result = `${h}时${m}分${s}秒`;
+    }
+    return result;
+}

+ 2 - 2
utils/userCache.js

@@ -19,13 +19,13 @@ export function useUserCache() {
 		}
 
 		const auth = cacheManager.get('auth');
-		console.log('auth:', auth)
+		// console.log('auth:', auth)
 		if (!auth) {
 			throw new Error('用户未登录!')
 			return;
 		}
 		const userId = auth.userId;
-		console.log('userId:', userId)
+		// console.log('userId:', userId)
 		if (!userId) {
 			throw new Error('数据异常用户Id异常!')
 			return;