chenxiong 3 سال پیش
والد
کامیت
a00cc63cc1

+ 2 - 0
common/api.js

@@ -21,8 +21,10 @@ import note from './httpList/note.js'
 import exam from './httpList/exam.js'
 import profileStamp from './httpList/profileStamp.js'
 import lock from './httpList/lock.js'
+import mock from './httpList/mock.js'
 
 export default {
+	...mock,
 	...login,
 	...polyvVideo,
 	...oss,

+ 14 - 2
common/httpList/course.js

@@ -160,7 +160,19 @@ export default {
 		})
 	},
 	
-	
-	
+	polyvLiveHistoryChatMsgList(data) {
+		return myRequest({
+			url: '/polyv/live/historyChatMsgList',
+			method: 'get',
+			data:data
+		})
+	},
+	studyRecordQueryLiveLast(data) {
+		return myRequest({
+			url: '/study/record/queryLiveLast',
+			method: 'get',
+			data:data
+		})
+	},
 	
 }

+ 9 - 1
common/httpList/goods.js

@@ -433,7 +433,15 @@ export default {
 			noToken:true
 			
 		})
-	}
+	},
+	
+	goodsLivingSectionList(data) {
+		return myRequest({
+			url: '/goods/livingSectionList',
+			method: 'get',
+			data:data
+		})
+	},
 	
 	
 	

+ 94 - 0
common/httpList/mock.js

@@ -0,0 +1,94 @@
+import {
+	myRequest
+} from '../request.js'
+export default {
+	mockApplyListApply(data) {
+		return myRequest({
+			url: '/mock/apply/listApply',
+			method: 'get',
+			data: data
+		})
+	},
+	
+	userSubscribe(data) {
+		return myRequest({
+			url: '/user/subscribe/'+data,
+			method: 'get',
+		})
+	},
+	
+	mockApplyListApplyBusiness(data) {
+		return myRequest({
+			url: '/mock/apply/listApplyBusiness',
+			method: 'get',
+		})
+	},
+	
+	mockSubscribe(data) {
+		return myRequest({
+			url: '/mock/subscribe',
+			method: 'post',
+			data
+		})
+	},
+	
+	mockSubscribeListSubscribe(data) {
+		return myRequest({
+			url: '/mock/subscribe/listSubscribe',
+			method: 'GET',
+			data
+		})
+	},
+	
+	mockRecord(data) {
+		return myRequest({
+			url: '/mock/record',
+			method: 'post',
+			data
+		})
+	},
+	
+	mockRecordEdit(data) {
+		return myRequest({
+			url: '/mock/record/edit',
+			method: 'post',
+			data
+		})
+	},
+	
+	mockWrongRecordWrongNum(data) {
+		return myRequest({
+			url:`/mock/wwrong/record/wrongNum/${data}`,
+			method: 'get'
+		})
+	},
+	
+	goodsListGoodsUserLive(data) {
+		return myRequest({
+			url:`/goods/listGoodsUserLive`,
+			method: 'get',
+			data
+		})
+	},
+	
+	mockReport(data) {
+		return myRequest({
+			url: '/mock/record/'+data,
+			method: 'get',
+		})
+	},
+	
+	mockWrongRecord(data) {
+		return myRequest({
+			url: '/mock/wwrong/record',
+			data:data,
+			method: 'POST',
+		})
+	},
+	
+	
+	
+	
+	
+	
+}

+ 10 - 0
common/httpList/study.js

@@ -29,5 +29,15 @@ export default {
 			method: 'get',
 			data: data
 		})
+	},
+	studyRecordGetLastLive(data) {
+		return myRequest({
+			url: '/study/record/getLastLive',
+			method: 'get',
+			data: data
+		})
 	}
+	
+	
 }
+

+ 1 - 0
common/methodTool.js

@@ -94,6 +94,7 @@ export default {
 		var NowTime = new Date(); //当前时间
 		//后台给我的是10位 精确到秒的 所有下面我就除以了1000,不要小数点后面的
 		var t = EndTime - (NowTime.getTime() / 1000).toFixed(0);
+		
 		if (t <= 0) {
 			return '已结束'
 		}

+ 6 - 2
common/request.js

@@ -5,14 +5,18 @@ import api from './api.js'
 var num = 1
 //接口api   
 // export const BASE_URL = 'https://api.xyyxt.net'   //release
-// export const BASE_URL = 'http://120.79.166.78:19009'   //预发布
-export const BASE_URL = 'http://42.192.164.187:19005'    //test 
+export const BASE_URL = 'http://api.xyyxt.net:19009'   //预发布
+// export const BASE_URL = 'http://42.192.164.187:19005'    //test 
 // export const BASE_URL = 'http://192.168.1.222:5055'    //dev
 
  //图片上传api
 // export const BASE_IMG_URL = 'https://file.xyyxt.net/'     //release
 export const BASE_IMG_URL = 'https://file-dev.xyyxt.net/'  //test
 
+
+// export const WEBVIEW_URL = 'http://192.168.1.38:8082/'  //test
+export const WEBVIEW_URL = 'http://api.xyyxt.net:6066/'  //预发布
+
 // export const socket_url = 'ws://42.192.164.187:19005/webSocket/'  //test
 // export const socket_url = 'ws://120.79.166.78:19009/webSocket/'  //预发布
 // export const socket_url = 'wss://api.xyyxt.net/webSocket/'  //release

+ 0 - 137
common/socket.js

@@ -1,137 +0,0 @@
-import store from '@/store/index.js'
-import method from '@/common/methodTool'
-let isSocketClose = false; // 是否关闭socket
-let heartbeatInterval = null; // 心跳定时器
-let socketTask = null; // websocket对象
-let againTimer = null; //断线重连定时器
-
-
-let url = null;
-
-/**
- * sockeUrl:websocet的地址
- * */
-const sokcet = (sockeUrl) => {
-	url = sockeUrl;
-	isSocketClose = false;
-	//判断是否有websocet对象,有的话清空
-	if (socketTask) {
-		socketTask.close();
-		socketTask = null;
-		clearInterval(heartbeatInterval);
-	}
-
-	// 连接
-	console.log(url)
-	socketTask = uni.connectSocket({
-		url: url,
-		success(data) {
-			console.log("websocket连接成功");
-			clearInterval(againTimer) //断线重连定时器
-		},
-		fail: (err) => {
-			console.log("报错", err);
-		}
-	});
-	// 连接打开
-	socketTask.onOpen((res) => {
-		console.log('WebSocket打开');
-		clearInterval(againTimer) //断线重连定时器
-		clearInterval(heartbeatInterval);
-		// // 30秒发送一次心跳
-		// heartbeatInterval = setInterval(() => {
-		// 	sendMsg('心跳ing')
-		// }, 30000)
-	})
-	// 监听连接失败
-	socketTask.onError((err) => {
-		console.log('WebSocket连接打开失败,请检查', err);
-		//停止发送心跳
-		clearInterval(heartbeatInterval)
-		//如果不是人为关闭的话,进行重连
-		if (!isSocketClose) {
-			reconnect(url)
-		}
-	})
-
-	// // 监听连接关闭 -
-	socketTask.onClose((e) => {
-		console.log('WebSocket连接关闭!',e);
-		clearInterval(heartbeatInterval)
-		if (!isSocketClose) {
-			reconnect(url)
-		}
-	})
-
-	// 监听收到信息
-	socketTask.onMessage((res) => {
-		console.log(res, 'res监听收到信息')
-		
-		if(res.data == 'offLine') {
-			stop();
-			uni.setStorageSync('needToLogin','1')
-			uni.showToast({
-				icon:'none',
-				title:'用户在其他终端登录,强制下线',
-				duration:3000,
-			})
-			setTimeout(() => {
-				method.exit();
-			},3000)
-		}
-	});
-
-
-}
-
-const reconnect = (url) => {
-	console.log('进入断线重连', isSocketClose);
-	clearInterval(againTimer) //断线重连定时器
-	clearInterval(heartbeatInterval);
-	console.log(socketTask)
-	socketTask && socketTask.close(); // 确保已经关闭后再重新打开
-	socketTask = null;
-	// 连接  重新调用创建websocet方法
-	againTimer = setInterval(() => {
-		sokcet(url)
-		console.log('在重新连接中...');
-	}, 20000)
-
-
-}
-
-const sendMsg = (msg) => { //向后端发送心跳包
-	console.log(msg)
-	try {
-		//通过 WebSocket 连接发送数据
-		socketTask.send({
-			data:msg
-		});
-	} catch (e) {
-		console.log(e,'msg')
-		if (isSocketClose) {
-			return
-		} else {
-			reconnect(url)
-		}
-
-	}
-}
-
-const stop = () => {
-	isSocketClose = true
-	clearInterval(heartbeatInterval);
-	clearInterval(againTimer) //断线重连定时器
-	socketTask && socketTask.close(); // 确保已经关闭后再重新打开
-	socketTask = null;
-}
-
-
-
-
-
-export const websocket = {
-	sokcet,
-	stop,
-	sendMsg
-};

+ 2 - 0
components/course/courseChapter.vue

@@ -9,6 +9,7 @@
       <view v-for="(itemM, indexM) in list" :key="indexM">
         <view v-if="itemM.type != 2">
           <courseSection
+						:isLive="isLive"
 						:orderGoodsId="orderGoodsId"
             :sectionMaxNum="sectionMaxNum"
             :preItem="list[indexM - 1] || preItem"
@@ -74,6 +75,7 @@ import courseSection from "@/components/course/courseSection.vue";
 export default {
   name: "courseChapter",
   props: {
+		isLive:false,
 		orderGoodsId:{
 			default:0
 		},

+ 3 - 1
components/course/courseModule.vue

@@ -7,7 +7,8 @@
 		</view>
 		<view v-show="!down">
 			<view v-for="(itemM,indexM) in list" :key="indexM">
-				<courseChapter :orderGoodsId="orderGoodsId" :preItem="list[indexM - 1] || preItem" :sectionMaxNum="sectionMaxNum" :needOpen="needOpen" @playEnd="playEnd($event)" @toDo="toDo($event)" :courseId="courseId" :learningOrder="learningOrder" :goodsId="goodsId" :isBuy="isBuy" :gradeId="gradeId" :isRebuild="isRebuild"  :menuItem="itemM" :levelId="levelId+'-'+itemM.chapterId"></courseChapter>
+				<courseChapter :orderGoodsId="orderGoodsId"
+						:isLive="isLive" :preItem="list[indexM - 1] || preItem" :sectionMaxNum="sectionMaxNum" :needOpen="needOpen" @playEnd="playEnd($event)" @toDo="toDo($event)" :courseId="courseId" :learningOrder="learningOrder" :goodsId="goodsId" :isBuy="isBuy" :gradeId="gradeId" :isRebuild="isRebuild"  :menuItem="itemM" :levelId="levelId+'-'+itemM.chapterId"></courseChapter>
 				<u-line v-if="indexM<list.length-1"></u-line>
 			</view>
 		</view>
@@ -20,6 +21,7 @@ import courseChapter from '@/components/course/courseChapter.vue';
 export default {
 	name: 'courseModule',
 	props: {
+		isLive:false,
 		orderGoodsId:{
 			default:0
 		},

+ 56 - 15
components/course/courseSection.vue

@@ -10,10 +10,18 @@
 					<view v-if="menuItem.sectionType==2" :class="playSectionId==newId && playNextId==playId?'color2':''">{{menuItem.name || ''}}</view>
 					<view v-if="menuItem.sectionType==3" :class="playSectionId==newId && playNextId==playId?'color3':''">{{menuItem.name || ''}}</view>
 					<view style="font-size: 20rpx;color: #FF3B30;" v-if="menuItem.sectionType==2 && menuItem.liveStartTime">
-						<view v-if="menuItem.liveStartTime>nowTime">
+						<view v-if="menuItem.liveStartTime>nowTime || !isBuy">
 							<text>{{$method.timestampToTime(menuItem.liveStartTime, isDay =false)}}</text>-
 							<text>{{$method.timestampToTime(menuItem.liveEndTime, isDay =false)}}</text>
 						</view>
+						<template v-if="isLast()">
+							<view v-if="liveLast.watchStatus == 'live'">
+								<text>直播中</text>
+							</view>
+							<view v-if="liveLast.watchStatus == 'end'">
+								<text>当前直播回放视频请稍后再查看</text>
+							</view>
+						</template>
 						<!-- <view v-if="menuItem.liveStartTime<=nowTime&&menuItem.liveEndTime>nowTime">
 							<text>直播中</text>
 						</view>
@@ -25,20 +33,28 @@
 				<view v-if="menuItem.sectionType==null">{{menuItem.name || ''}}</view>
 			</view>
 			<view style="font-size: 20rpx;color: #FF3B30;"  v-if="menuItem.liveStartTime && menuItem.sectionType != 3 && isBuy">
-				<view class="tagWillPlay" v-if="menuItem.liveStartTime>nowTime">
-					<text>待开播</text>
-				</view>
-				<view class="tagPlaying" v-if="menuItem.liveStartTime<=nowTime&&menuItem.liveEndTime>nowTime">
-					<text>直播中</text>
-				</view>
-				<view class="tagPlayed" v-if="menuItem.liveEndTime<nowTime">
-					<text>已结束</text>
-				</view>
-			</view>
-			<view v-if="(isRebuild||menuItem.rebuild>0)" class="tagRe">待重修</view>
-			<view v-else>
-				<view v-if="menuItem.learning==1" class="tagGreen">已看完</view>
+				
+				<template v-if="!isLast()">
+					<view class="tagWillPlay" v-if="menuItem.liveStartTime>nowTime">
+						<text>待开播</text>
+					</view>
+					<view class="tagPlaying" v-if="menuItem.liveStartTime<=nowTime&&menuItem.liveEndTime>nowTime">
+						<text>直播中</text>
+					</view>
+					<view class="tagPlayed" v-if="menuItem.liveEndTime<nowTime">
+						<text>已结束</text>
+					</view>
+				</template>
+				
 			</view>
+			<!-- 直播课程没有学习状态 -->
+			<template v-if="!isLive">
+				<view v-if="(isRebuild||menuItem.rebuild>0)" class="tagRe">待重修</view>
+				<view v-else>
+					<view v-if="menuItem.learning==1" class="tagGreen">已看完</view>
+				</view>
+			</template>
+			
 			
 		</view>
 		<view v-if="menuItem.tryListen&&!isBuy" class="tryBox">
@@ -50,9 +66,11 @@
 <script>
 import { mapGetters } from 'vuex';
 import eventHub from '@/common/eventHub.js'
+import {WEBVIEW_URL} from '@/common/request.js'
 export default {
 	name: 'courseSection',
 	props: {
+		isLive:false,
 		orderGoodsId:{
 			default:0
 		},
@@ -120,6 +138,8 @@ export default {
 	mounted() {
 		this.nowTime = Number(new  Date().getTime()/1000).toFixed(0)
 		this.newId= this.menuItem.sectionId>0?this.menuItem.sectionId:this.menuItem.menuId
+		console.log(this.newId,'this.newId')
+		console.log(this.playSectionId,'this.playSectionId')
 		console.log(this.isRebuild)
 		console.log(this.nextMenuItem,'nextMenuItem')
 		console.log(this.menuItem,'this.menuItem')
@@ -173,6 +193,18 @@ export default {
 		});
 	},
 	methods: {
+		isLast() {
+			if(this.liveLast) {
+				let sectionASame = this.liveLast.sectionId == (this.menuItem.sectionId || this.menuItem.menuId)
+				let chapterSame = this.liveLast.chapterId == (this.menuItem.chapterId || 0)
+				let moduleSame = this.liveLast.moduleId == (this.menuItem.moduleId || 0);
+
+				return sectionASame && chapterSame && moduleSame
+			} else {
+				return false;
+			}
+			
+		},
 		studyRecordMenuAllList() {
 			return new Promise(resolve => {
 				
@@ -408,6 +440,15 @@ export default {
 					this.clickLock = false;
 					return
 				}
+				let moduleId = this.menuItem.moduleId || 0;
+				let chapterId = this.menuItem.chapterId || 0;
+				let sectionId = this.menuItem.sectionId || this.menuItem.menuId;
+				let encode = encodeURIComponent(WEBVIEW_URL+'pages/live/index?token='+uni.getStorageSync('token')+'&userInfo='+JSON.stringify(this.userInfo)+'&channelId='+this.menuItem.liveUrl+'&gradeId='+this.gradeId+'&courseId='+this.courseId+'&goodsId='+this.goodsId+'&orderGoodsId='+this.orderGoodsId+'&sectionId='+sectionId+'&chapterId='+chapterId+'&moduleId='+moduleId)
+				uni.navigateTo({
+					url:`../../pages/webview/index?url=`+encode
+				})
+				
+				return;
 				//设置播放的节ID
 				this.$store.commit('setPlaySectionId', {playSectionId  :this.newId});
 				this.$store.commit('setPlayChannelId', {playChannelId  :this.menuItem.liveUrl});
@@ -426,7 +467,7 @@ export default {
 			}
 		}
 	},
-	computed: { ...mapGetters(['playSectionId','playChannelId','playVID','playNextId']) }
+	computed: { ...mapGetters(['playSectionId','playChannelId','playVID','playNextId','userInfo','liveLast']) }
 	
 };
 </script>

+ 77 - 0
pages.json

@@ -738,6 +738,23 @@
 					}
 				}
 			}
+		},{
+			"path": "live/detail",
+			"style": {
+				"navigationBarTitleText": "商品详情",
+				"navigationBarBackgroundColor": "#0386FD",
+				"navigationBarTextStyle": "white",
+				"navigationStyle": "custom", // 隐藏系统导航栏
+				"app-plus": {
+					"titleNView": false, //禁用原生导航栏 
+					"bounce": "none"
+				},
+				"mp-weixin": {
+					"usingComponents": {
+						"polyv-player": "plugin://polyv-player/player"
+					  }
+				}
+			}
 		}],
 		"plugins": {
 			"polyv-player": {
@@ -788,6 +805,42 @@
 					"bounce": "none"
 				}
 			}
+		},{
+			"path": "liveDetail/index",
+			"style": {
+				"navigationBarTitleText": "商品详情",
+				"navigationBarBackgroundColor": "#0386FD",
+				"navigationBarTextStyle": "white",
+				"navigationStyle": "custom", // 隐藏系统导航栏
+				"app-plus": {
+					"titleNView": false, //禁用原生导航栏 
+					"bounce": "none"
+				}
+			}
+		},{
+			"path": "liveDetail/list",
+			"style": {
+				"navigationBarTitleText": "直播课列表",
+				"navigationBarBackgroundColor": "#0386FD",
+				"navigationBarTextStyle": "white",
+				"navigationStyle": "custom", // 隐藏系统导航栏
+				"app-plus": {
+					"titleNView": false, //禁用原生导航栏 
+					"bounce": "none"
+				}
+			}
+		},{
+			"path": "liveDetail/course",
+			"style": {
+				"navigationBarTitleText": "课程列表",
+				"navigationBarBackgroundColor": "#0386FD",
+				"navigationBarTextStyle": "white",
+				"navigationStyle": "custom", // 隐藏系统导航栏
+				"app-plus": {
+					"titleNView": false, //禁用原生导航栏 
+					"bounce": "none"
+				}
+			}
 		},{
 			"path": "examList/index",
 			"style": {
@@ -824,6 +877,30 @@
 					"bounce": "none"
 				}
 			}
+		},{
+			"path": "examReport/questionBankAllExplain",
+			"style": {
+				"navigationBarTitleText": "全部解析",
+				"navigationBarBackgroundColor": "#0386FD",
+				"navigationBarTextStyle": "white",
+				"navigationStyle": "custom", // 隐藏系统导航栏
+				"app-plus": {
+					"titleNView": false, //禁用原生导航栏 
+					"bounce": "none"
+				}
+			}
+		},{
+			"path": "examReport/questionBankWrongExplain",
+			"style": {
+				"navigationBarTitleText": "错题解析",
+				"navigationBarBackgroundColor": "#0386FD",
+				"navigationBarTextStyle": "white",
+				"navigationStyle": "custom", // 隐藏系统导航栏
+				"app-plus": {
+					"titleNView": false, //禁用原生导航栏 
+					"bounce": "none"
+				}
+			}
 		},{
 			"path": "examBank/index",
 			"style": {

+ 68 - 0
pages/course/index.vue

@@ -35,6 +35,15 @@
 						</view>
 					</scroll-view>
 				</view>
+				<view class="menuSel" v-show="current==2">
+					<scroll-view class="r_sliper" scroll-x="true" >
+						<view v-for="(item,index) in sList" :key="index" style="margin-right: 20rpx;display:inline-block">
+							<view :class="paramList[2].subjectId==item.id?'r_t1':'r_t2'" @click="cMenu2(item.id)">
+								{{item.subjectName}}
+							</view>
+						</view>
+					</scroll-view>
+				</view>
 			</view>
 			<view v-show="current==0">
 				<view class="listBox">
@@ -82,6 +91,31 @@
 					<view class="emptyTip" v-if="list2.length==0">暂未上架相关题库~</view>
 				</view>
 			</view>
+			
+			<view v-show="current==2">
+				<view class="listBox">
+					<navigator  hover-class="none" :url="'/pages5/liveDetail/index?id='+item.goodsId" v-for="(item,index) in list3" :key="index" >
+						<view class="itemBox">
+							<image :src="$method.splitImgHost(item.coverUrl, true)" style="height: 367rpx;width: 100%;border-radius: 24rpx;"></image>
+							<view style="display: flex;margin-top: 13rpx;align-items: center;">
+								<view class="yearTag" v-if="item.year">{{item.year}}</view>
+								<view class="titleTag" style="display: flex;justify-content: space-between;flex:1;">
+									<view style="flex:1;">{{item.goodsName}}</view>
+									
+									<view class="priceTag">¥ {{item.standPrice.toFixed(2)}}</view>
+								</view>
+							</view>
+							<view style="display: flex;justify-content: space-between;margin-top: 13rpx;" v-if="false">
+								<view class="noteTag">
+									<image src="/static/icon/wk_icon1.png" class="wk_icon"></image>
+									<view class="priceTag">¥ {{item.standPrice.toFixed(2)}}</view>
+								</view>
+							</view>
+						</view>
+					</navigator>
+					<view class="emptyTip" v-if="list3.length==0">暂未上架相关直播~</view>
+				</view>
+			</view>
 		</view>
 		<view v-show="show" class="popuBox">
 			<view class="flex-d" >
@@ -114,6 +148,9 @@ export default {
 				},
 				{
 					name: '题库通'
+				},
+				{
+					name: '直播课'
 				}
 			],
 			array:['全部','建设工程施工管理','机电全科','机电工程管理与实','机电全科','全科'],
@@ -136,10 +173,19 @@ export default {
 					showStatus: 0,
 					goodsType:2,
 					subjectId:0
+				},
+				{
+					pageNum: 1,
+					pageSize: 10,
+					total: 0,
+					showStatus: 0,
+					goodsType:6,
+					subjectId:0
 				}
 			],
 			list1: [],
 			list2: [],
+			list3:[],
 			eList:[],
 			bList:[],
 			sList:[],
@@ -238,8 +284,10 @@ export default {
 			this.paramList[1].pageNum = 1
 			this.list1 = []
 			this.list2 = []
+			this.list3 = [];
 			this.courseList();
 			this.bankList();
+			this.liveList()
 			this.educationList()
 		},
 		cMenu(index){
@@ -256,6 +304,14 @@ export default {
 		//	this.menuIndex1 = index;
 			this.bankList();
 		},
+		
+		cMenu2(index){
+			this.paramList[2].pageNum = 1
+			this.paramList[2].subjectId= index;
+			this.list3 = []
+		//	this.menuIndex1 = index;
+			this.liveList();
+		},
 		change(index){
 			this.current = index;
 		},
@@ -283,6 +339,18 @@ export default {
 				}
 			});
 		},
+		//直播
+		liveList() {
+			var self = this;
+			var param = this.paramList[2];
+			this.$api.goodsList(param).then(res => {
+				self.paramList[2].total = res.data.total;
+				self.list3.push.apply(self.list3, res.data.rows);
+				if (self.list3.length === res.data.total) {
+					self.paramList[2].showStatus = true;
+				}
+			});
+		},
 	},
 	onReachBottom() {
 		if (this.current == 0) {

+ 1 - 0
pages/index/index.vue

@@ -394,6 +394,7 @@ export default {
 			var self = this;
 			var param = this.paramList[0];
 			this.$api.goodsList(param).then(res => {
+				console.log(res,'res')
 				self.paramList[0].total = res.data.total;
 				self.list1 = res.data.rows;
 				if (self.list1.length === res.data.total) {

+ 29 - 2
pages/wd/index.vue

@@ -38,6 +38,17 @@
 						<view>我的题库通</view>
 					</view>
 				</view>
+				<navigator  hover-class="none" url="/pages5/liveDetail/list" class="menu_box" >
+					<view class="box_left">
+						<image src="/static/icon/my_icon2.png" class="my_icon"></image>
+						<view>我的直播课</view>
+					</view>
+					<view class="box_right">
+						
+						<text>{{ total2 }}</text>
+						个课程直播中
+					</view>
+				</navigator>
 				<navigator  hover-class="none" url="/pages2/learn/my_learn" class="menu_box" >
 					<view class="box_left">
 						<image src="/static/icon/my_icon2.png" class="my_icon"></image>
@@ -55,7 +66,7 @@
 						<view>我的模考</view>
 					</view>
 					<view class="box_right">
-						<text>{{ userNums.periodSum }}</text>
+						<text>{{ total1 }}</text>
 						个模考预约
 					</view>
 				</navigator>
@@ -116,7 +127,9 @@ export default {
 			content: '此功能暂未开放',
 			show: false,
 			isLogin: false,
-			userNums: {}
+			userNums: {},
+			total1:0,
+			total2:0,
 		};
 	},
 	onLoad(option) {
@@ -127,11 +140,25 @@ export default {
 		if(this.isLogin){
 		this.$store.state.allowLoading = false;
 		this.getNums();
+		this.getCount();
+		this.goodsLivingSectionList();
 		this.$store.state.allowLoading = true;
 		}
 		// this.$store.dispatch('changeTabsNum')
 	},
 	methods: {
+		getCount() {
+			this.$api.mockSubscribeListSubscribe({
+				mockStatus:0,
+			}).then(res => {
+				this.total1 = res.data.total
+			})
+		},
+		goodsLivingSectionList() {
+			this.$api.goodsLivingSectionList().then(res => {
+				this.total2 = res.data.total
+			})
+		},
 		goBank() {
 			this.$api.lockLockStatus({
 			  action:'bank'

+ 1 - 0
pages/webview/index.vue

@@ -19,6 +19,7 @@ export default {
 	},
 	onLoad(option) {
 		this.url = decodeURIComponent(option.url);
+		console.log(this.url)
 	},
 	methods: {
 		

+ 1 - 1
pages2/order/confirm_pay.vue

@@ -192,7 +192,7 @@ export default {
 								type = 3;
 							}
 						}
-						this.confirmText = type == 1 ? "继续选课" : type == 2 ? "继续选题" : type == 3 ? "继续选购" :"";
+						this.confirmText = (type == 1 || type == 6) ? "继续选课" : type == 2 ? "继续选题" : type == 3 ? "继续选购" :"";
 					}
 					
 				} else {

+ 3 - 3
pages2/verify/input.vue

@@ -28,7 +28,7 @@
               :disabled="true"
 							:prop="item.required ? item.fieldKey : ''"
 						>
-							<u-input v-model="form.name" :placeholder="`请输入${item.fieldName}`" />
+							<u-input disabled v-model="form.name" :placeholder="`请输入${item.fieldName}`" />
 						</u-form-item>
 						<u-form-item
 							:key="index"
@@ -39,7 +39,7 @@
               :disabled="true"
 							:prop="item.required ? item.fieldKey : ''"
 						>
-							<u-input v-model="form.idcard" :placeholder="`请输入${item.fieldName}`" />
+							<u-input disabled v-model="form.idcard" :placeholder="`请输入${item.fieldName}`" />
 						</u-form-item>
 						<u-form-item
 							:key="index"
@@ -50,7 +50,7 @@
               :disabled="true"
 							:prop="item.required ? item.fieldKey : ''"
 						>
-							<u-input v-model="form.telphone" :placeholder="`请输入${item.fieldName}`" />
+							<u-input disabled v-model="form.telphone" :placeholder="`请输入${item.fieldName}`" />
 						</u-form-item>
 						<u-form-item
 							:key="index"

+ 2622 - 0
pages3/live/detail.vue

@@ -0,0 +1,2622 @@
+<template>
+  <view class="polyv_detail">
+    <nav-bar
+      :title="detail.courseName || '课程详情'"
+      v-show="navShow"
+    ></nav-bar>
+    <view id="top">
+      <view class="video_box" v-if="!startStatus">
+        <image
+          :src="$method.splitImgHost(detail.coverUrl)"
+          mode="widthFix"
+          style="width: 100%; height: 460rpx"
+        ></image>
+        <image
+          v-if="false"
+          class="video_play"
+          src="/static/play.png"
+          @click="startVideo"
+        ></image>
+      </view>
+      <view v-else>
+        <view
+          class="video_box"
+          style="width: 100%; height: 460rpx"
+          v-if="playVID"
+        >
+          <polyv-player
+            id="playerVideo"
+            playerId="playerVideo"
+            height="460rpx"
+            :vid="vid"
+            :showSettingBtn="true"
+            :enablePlayGesture="true"
+            :custom-cache="false"
+            :object-fit="'contain'"
+            @statechange="onStateChange"
+            @fullscreenchange="fullscreenchange"
+            @error="playError"
+            :autoplay="true"
+						:page-gesture="true"
+						:vslide-gesture="true"
+						:vslide-gesture-in-fullscreen="true"
+            :isAllowSeek="isAllowSeek"
+            :playbackRate="playbackRate"
+            :startTime="startTime"
+            :enableAutoRotation="enableAutoRotation"
+						@loadedmetadata="loadedmetadata"
+          ></polyv-player>
+          <cover-view
+            class="video-toast__close"
+            v-if="videoToastShow"
+            @click="closeToast()"
+            >X</cover-view
+          >
+          <cover-view class="video-toast" v-if="videoToastShow">
+            <cover-view class="video-toast__text"
+              >您上次看到 {{ seekTime }},正在自动续播</cover-view
+            >
+            <cover-view class="video-toast__btn" @click="restart()"
+              >从头播放</cover-view
+            >
+          </cover-view>
+        </view>
+        <view
+          class="video_box"
+          style="width: 100%; height: 460rpx"
+          v-if="playChannelId > 0"
+        >
+          <player
+            class="plv-mp-demo-player"
+            :videoOption="videoOption"
+						:page-gesture="true"
+						:vslide-gesture="true"
+						:vslide-gesture-in-fullscreen="true"
+            @onLiveStatusChange="playerLiveStatusChange"
+          />
+        </view>
+      </view>
+      <view>
+        <u-row>
+          <u-col span="10">
+            <view class="video_t1">{{ detail.courseName }}</view>
+          </u-col>
+          <u-col span="2">
+            <div class="notice_wrap" v-if="goodsData.buyNote">
+              <view class="video_t1_t" @click="studyNotice"> 学员须知 </view>
+            </div>
+          </u-col>
+        </u-row>
+      </view>
+      <u-line color="#D6D6DB" />
+      <view>
+        <view
+          ><u-tabs
+            gutter="0"
+            :item-width="itemWidth()"
+            :list="list"
+            font-size="32"
+            bar-width="24"
+            :current="current"
+            @change="change"
+            active-color="#007AFF"
+          ></u-tabs
+        ></view>
+      </view>
+      <u-line color="#D6D6DB" />
+    </view>
+    <view class="box">
+      <scroll-view class="box_in" scroll-y="true">
+        <!--目录 -->
+        <view v-show="current == 0">
+					<view class="top__header" v-if="livingItem" @click="goLive(livingItem)">
+						<image class="img" src="/pages5/static/live.png" mode="widthFix"></image>
+						<view class="note">正在直播中</view>
+						<view class="title">{{livingItem.sectionName}}</view>
+					</view>
+          <view class="menuBox" v-for="(item, index) in menuList" :key="index">
+            <!--模块 -->
+            <view v-if="item.type == 1"
+              ><courseModule
+								:isLive="true"
+								:orderGoodsId="orderGoodsId"
+                :sectionMaxNum="goodsData.sectionMaxNum"
+                :needOpen="menuIndex[0] === index ? true : false"
+                :courseId="courseId"
+                :preItem="menuList[index - 1]"
+                :learningOrder="businessData.goodsLearningOrder"
+                :goodsId="goodsId"
+                :gradeId="gradeId"
+                :isBuy="true"
+                :menuItem="item"
+                :levelId="item.menuId"
+              ></courseModule
+            ></view>
+            <!--章 -->
+            <view v-if="item.type == 2"
+              ><courseChapter
+								:isLive="true"
+								:orderGoodsId="orderGoodsId"
+                :sectionMaxNum="goodsData.sectionMaxNum"
+                :needOpen="menuIndex[0] === index ? true : false"
+                :courseId="courseId"
+                :preItem="menuList[index - 1]"
+                @playEnd="sectionPlayEnd($event, index)"
+                :learningOrder="businessData.goodsLearningOrder"
+                :goodsId="goodsId"
+                :gradeId="gradeId"
+                :isBuy="true"
+                :menuItem="item"
+                :levelId="'0-' + item.menuId"
+              ></courseChapter
+            ></view>
+            <!--节 -->
+            <view v-if="item.type == 3"
+              ><courseSection
+								:isLive="true"
+								:orderGoodsId="orderGoodsId"
+                :sectionMaxNum="goodsData.sectionMaxNum"
+                @playEnd="sectionPlayEnd($event, index)"
+                :courseId="courseId"
+                :preItem="menuList[index - 1]"
+                :learningOrder="businessData.goodsLearningOrder"
+                :goodsId="goodsId"
+                :gradeId="gradeId"
+                :isBuy="true"
+                :menuItem="item"
+                :levelId="'0-0-' + item.menuId"
+              ></courseSection
+            ></view>
+          </view>
+        </view>
+        <!--笔记 -->
+        <view v-show="current == 1">
+          <view v-if="noteList.length == 0" style="text-align: center"
+            >暂无笔记</view
+          >
+          <view class="inputBottom" v-if="!(isPlayRebuild > 0) && playChannelId ==0">
+            <view style="width: 10%"
+              ><image
+                src="/static/icon/note3.png"
+                style="width: 39rpx; height: 39rpx; margin: 0 29rpx"
+              ></image
+            ></view>
+            <view style="width: 73%; height: 100%; padding: 10rpx 0">
+              <u-input
+                class="input"
+                height="60"
+                fixed="true"
+                placeholder="您可以在这里输入笔记内容"
+                type="input"
+                :custom-style="inputStyle"
+                v-model="noteValue"
+              />
+            </view>
+            <view
+              style="
+                color: #007aff;
+                font-size: 30rpx;
+                font-weight: bold;
+                width: 15%;
+                text-align: center;
+              "
+              @click="postNote"
+              >提交</view
+            >
+          </view>
+          <view v-for="(item, index) in noteList" :key="index">
+            <view class="dateBox">{{
+              $method.timestampToTime(item.dateNote)
+            }}</view>
+            <view class="noteBox">
+              <view
+                v-for="(item1, index1) in item.userNotes"
+                :key="index1"
+                style="margin-top: 30rpx"
+                @click="jumpNote(item1)"
+              >
+                <view style="display: flex">
+                  <view>
+                    <view>
+                      <image
+                        src="/static/icon/note2.png"
+                        v-if="noteId != item1.noteId"
+                        style="width: 39rpx; height: 39rpx; margin: 0 29rpx"
+                      ></image>
+                      <image
+                        src="/static/icon/note1.png"
+                        v-if="noteId == item1.noteId"
+                        style="width: 39rpx; height: 39rpx; margin: 0 29rpx"
+                      ></image>
+                    </view>
+                    <view
+                      class="title"
+                      style="width: 39rpx; height: 39rpx; margin: 0 29rpx"
+                      >{{ $method.secondToDate(item1.noteSecond) }}</view
+                    >
+                  </view>
+                  <view style="margin-left: 10rpx">
+                    <view class="t2Content leftPadding">{{
+                      item1.sectionName
+                    }}</view>
+                    <view class="tBox2">{{ item1.noteText }}</view>
+                  </view>
+                </view>
+              </view>
+            </view>
+          </view>
+        </view>
+        <!--答疑 -->
+        <view v-show="current == 2">
+          <view class="inputBottom">
+            <view class="flex_auto">
+              <u-input
+                height="60"
+                fixed="true"
+								:focus="isFocus"
+                :placeholder="placeholder"
+                type="input"
+								@blur="blur"
+                :custom-style="inputStyle"
+                v-model="ctxValue"
+              />
+            </view>
+            <view class="btn" @click="postContent">提交</view>
+          </view>
+          <view
+            v-for="(item, index) in answerList"
+            :key="index"
+            style="background-color: #ffffff; margin-bottom: 20rpx"
+          >
+            <view class="chat_box" @click.stop="clearCtx">
+              <view style="display: flex; flex: 1">
+                <view
+                  ><image
+                    :src="
+                      item.assignUserId > 0 && !item.realname
+                        ? '/static/logo_xcx.png'
+                        : $method.splitImgHost(item.avatar)
+                    "
+                    style="width: 64rpx; height: 64rpx"
+                  ></image
+                ></view>
+                <view style="margin-left: 15rpx">
+                  <view class="chat1">{{
+                    item.assignUserId > 0 && !item.realname
+                      ? "祥粤老师"
+                      : item.realname
+                  }}</view>
+                  <view class="chat2">{{
+                    $method.timestampToTime(item.createTime, false)
+                  }}</view>
+                  <view class="chat3">
+                    <text v-if="item.assignUserId > 0">回复</text>
+                    <text v-if="item.assignUserId > 0" style="color: #007aff"
+                      >@{{ item.assignRealname }}</text
+                    >
+                    <view style="word-break: break-all">{{
+                      item.answerText
+                    }}</view>
+                  </view>
+                </view>
+              </view>
+              <view
+                class="btnReply"
+                @click.stop="replyContent(item)"
+                v-if="item.userId != userInfo.userId"
+                >回复</view
+              >
+              <view v-else class="btnDel" @click.stop="delContent(item)"
+                >删除</view
+              >
+            </view>
+            <u-line color="#D6D6DB" />
+          </view>
+          <view v-if="answerList.length == 0" style="text-align: center"
+            >暂无记录</view
+          >
+        </view>
+				<!--答疑 -->
+				<view v-show="current == 3">
+				  
+				  <view
+				    v-for="(item, index) in historyChatMsgList"
+				    :key="index"
+				    style="background-color: #ffffff; margin-bottom: 20rpx"
+				  >
+				    <view class="chat_box" @click.stop="clearCtx">
+				      <view style="display: flex; flex: 1">
+				        <view
+				          ><image
+				            :src="
+				              item.user.pic
+				            "
+				            style="width: 64rpx; height: 64rpx"
+				          ></image
+				        ></view>
+				        <view style="margin-left: 15rpx">
+				          <view class="chat1">{{
+				            item.user.nickname
+				          }}</view>
+				          <view class="chat2">{{
+				            item.time | formatDate
+				          }}</view>
+									<view class="chat3">
+									  <!-- <text v-if="item.assignUserId > 0">回复</text>
+									  <text v-if="item.assignUserId > 0" style="color: #007aff"
+									    >@{{ item.assignRealname }}</text
+									  > -->
+									  <view style="word-break: break-all">{{
+									    item.content
+									  }}</view>
+									</view>
+				        </view>
+								
+				      </view>
+				    </view>
+				    <u-line color="#D6D6DB" />
+				  </view>
+				  <view v-if="historyChatMsgList.length == 0" style="text-align: center"
+				    >暂无记录</view
+				  >
+				</view>
+      </scroll-view>
+    </view>
+    <!-- 播放前拍照end -->
+    <u-popup
+      v-model="showSet"
+      :mask-close-able="false"
+      mode="center"
+      border-radius="24"
+    >
+      <view
+        style="
+          align-items: center;
+          padding: 0 40rpx;
+          display: flex;
+          flex-direction: column;
+          justify-content: center;
+        "
+      >
+        <view
+          style="
+            font-weight: bold;
+            color: #333333;
+            font-size: 30rpx;
+            margin-top: 30rpx;
+          "
+          >温馨提示</view
+        >
+        <view
+          style="
+            width: 457rpx;
+            color: #666666;
+            font-size: 30rpx;
+            margin-top: 30rpx;
+          "
+          >学习过程中需要拍照验证学员身份, 拍照功能需要使用您的相机。
+          是否授权使用?</view
+        >
+        <view style="margin: 40rpx 0">
+          <button
+            open-type="openSetting"
+            @bindopensetting="openSetting"
+            class="btnSet"
+          >
+            去授权
+          </button>
+        </view>
+      </view>
+    </u-popup>
+
+    <u-mask :show="photoPopup">
+      <!-- 播放前拍照start -->
+      <view
+        v-if="photoPopup"
+        :mask-close-able="false"
+        style="bottom: 0; position: fixed; width: 100%; z-index: 999"
+      >
+        <view class="photoBox">
+          <view class="photoTop">
+            <view class="sqzz" v-if="false"
+              ><u-icon
+                name="close"
+                color="#333333"
+                size="30"
+                @click="closePhoto"
+              ></u-icon
+            ></view>
+            <view class="centersq">请正视手机屏幕</view>
+            <view class="sqzz"></view>
+          </view>
+          <view class="photoCenter">
+            <view
+              style="width: 100%; height: 979rpx; position: fixed"
+              v-if="photoPopup && isTaking"
+            >
+              <camera
+                device-position="front"
+                flash="off"
+                @error="error"
+                style="width: 100%; height: 100%"
+              ></camera>
+            </view>
+            <view class="custom" v-if="!isTaking"
+              ><image :src="avatarUrl" mode=""></image
+            ></view>
+          </view>
+          <view class="btns">
+            <view class="btnResult" v-if="isTaking" @click="takePhoto"
+              >拍照</view
+            >
+            <view class="btnResult" v-if="!isTaking" @click="reTake">重拍</view>
+            <view class="btnResult" v-if="!isTaking" @click="submit">确认</view>
+          </view>
+        </view>
+      </view>
+    </u-mask>
+
+    <u-popup
+      v-model="noticeShow"
+      class="notice_modal"
+      mode="center"
+      border-radius="14"
+      width="700rpx"
+      height="900rpx"
+    >
+      <div class="content">
+        <scroll-view scroll-y="true" style="height: 100%">
+          <view class="title">学员须知</view>
+          <text class="text">
+            {{ goodsData.buyNote }}
+          </text>
+        </scroll-view>
+      </div>
+    </u-popup>
+		
+		
+  </view>
+</template>
+
+<script>
+import plv from "@/pages3/static/polyv-sdk/index";
+import courseModule from "@/components/course/courseModule.vue";
+import courseChapter from "@/components/course/courseChapter.vue";
+import courseSection from "@/components/course/courseSection.vue";
+import {WEBVIEW_URL} from '@/common/request.js'
+// import { websocket } from "@/common/socket.js";
+import { mapGetters, mapMutations } from "vuex";
+export default {
+  components: {
+    courseModule,
+    courseChapter,
+    courseSection,
+  },
+	filters: {
+		formatDate(date) {
+			const nDate = new Date(date)
+			const nyear = nDate.getFullYear()
+			const nmonth = (nDate.getMonth()+1).toString().padStart(2,0)
+			const nday = nDate.getDate().toString().padStart(2,0)
+			const hour = nDate.getHours()
+			const mins = nDate.getMinutes()
+			const seconds = nDate.getSeconds()
+			return nyear+'-'+nmonth+'-'+nday+' '+hour+':'+(mins>=10 ? mins : '0'+mins)+':'+(seconds>=10 ? seconds : '0'+seconds)
+		}
+	},
+  data() {
+    return {
+			hasStart:false,
+			channelItem:null,
+      lockTimer: null,
+      orderGoodsId: 0,
+      noticeShow: false,
+      navShow: true,
+      enableAutoRotation: true,
+      seekTime: "",
+      toastTimer: null,
+      videoToastShow: false,
+      initLiveOk: false,
+      livePlay: false, //是否正在播放直播,不含暂停
+      liveDuration: 0, //直播观看时长
+      videoOption: {
+        mode: "live",
+        uid: "",
+        cid: "",
+        openId: "",
+        isAutoChange: false,
+        forceVideo: false,
+      },
+      courseHandoutsData: "",
+      liveDetail: {},
+      showSet: false,
+      startStatus: false,
+      detail: {},
+      courseId: 0,
+      placeholder:
+        "您可以在这里输入笔记内容\n还可以点击左侧图标为笔记加上时间标记",
+      inputStyle: {
+        background: "rgba(244, 244, 244, 0.98)",
+        borderRadius: "24rpx",
+        padding: "8rpx",
+        marginBottom: "10rpx",
+      },
+      list: [{
+					name: "目录",
+				},
+				{
+					name: "笔记",
+				},
+				{
+					name: "答疑",
+				},
+				{
+					name: "聊天",
+				}],
+      menuList: [],
+      current: 0,
+      vid: "",
+      goodsId: 0,
+      goodsData: {},
+      photoPopup: false,
+      goodsPlayConfig: null,
+      autoplay: false,
+      isAllowSeek: "no",
+      playbackRate: [1.0],
+      timer: null,
+      answerTimer: null,
+      goodsPhotographConfig: null,
+      intervalTimeList: [], // 间隔拍照时长
+      intervalTimeIndex: 0, //当前处于哪个时间段拍照
+      playTime: 0, //页面播放时长,不含暂停
+      currentTime: 0,
+      avatarUrl: "",
+      ossAvatarUrl: "",
+      studyDuration: 0, // 当前视频时长
+      gradeId: 0,
+      chapterId: 0,
+      moduleId: 0,
+      reMenuList: [],
+      answerList: [],
+      assignUserId: 0,
+      placeholder: "您可以在这里输入答疑内容",
+      ctxValue: "",
+      noteList: [],
+      noteValue: "",
+      noteId: 0,
+      recordObj: 0,
+      gradeDetail: {},
+      isTaking: true, //是否正在拍照
+      needSeek: false, //第一次播放是否需要跳转
+      needProfileModal: false, //是否需要资料审核弹框
+      liveObj: {},
+      photoNum: 0,
+      photoList: [], //拍照的时间点
+      photoConfig: false, //是否配置好拍照次数
+      photoIndex: 0, //当前位于拍照的区间下标 从0开始
+      photoHistoryList: [], //已拍照历史的下标点
+      sectionItem: null,
+      businessData: {},
+      showNotes: true,
+      menuIndex: [],
+      uploadLock: false, //上传图片
+      isPlayRebuild: false, //是否正在播放重修视频
+      isRebuild: false, //视频是否从重修目录点击
+			isFocus:false,
+			clearTimer:null,
+			historyChatMsgList:[],
+			livingItem:''
+    };
+  },
+  computed: {
+    ...mapGetters(["userInfo", "playSectionId", "playChannelId", "playVID"]),
+  },
+  onLoad(option) {
+    this.courseId = Number(option.courseId);
+    this.goodsId = Number(option.goodsId);
+		// this.gradeId = option.gradeId || 0
+    this.orderGoodsId = Number(option.orderGoodsId) || '';
+		this.updateLiveLast(null)
+    this.courseDetail();
+    this.getGoodsDetail();
+    this.getAnswerList();
+		this.studyRecordMenuAllList();
+    this.answerTimer = setInterval(() => {
+      this.getAnswerList();
+    }, 5000);
+    let noteSecond = Number(option.noteSecond);
+    if (noteSecond > 0) {
+      //我的消息跳过来,播放节
+      let item = {
+        sectionId: Number(option.sectionId),
+        recordingUrl: option.recordingUrl,
+        noteSecond: noteSecond,
+        studyDuration: noteSecond,
+      };
+      let playNextId = `moduleId${option.moduleId}chapterId${
+        option.chapterId
+      }sectionId${option.sectionId}${option.isRebuild ? "isRebuild" : ""}`;
+      this.$store.commit("setPlaySectionId", { playSectionId: item.sectionId });
+      this.$store.commit("setPlayVID", { playVID: item.recordingUrl });
+      this.$store.commit("updatePlayNextId", playNextId);
+      console.log("this.playNoteVideo");
+			
+			this.playNoteVideo(item)
+    } else {
+			this.studyRecordQueryLiveLast();
+		}
+  },
+  onShow() {
+    var self = this;
+    //相机授权
+		// this.userConfirmInfoDetail().then(res => {
+			
+		// })
+		
+		// this.getbaseprofiletplists();
+    
+    console.log(this.gradeId, 7512);
+  },
+	onHide() {
+		
+	},
+  onUnload() {
+    if (this.playSectionId > 0 && this.hasStart) {
+      //退出提交记录
+      this.postStudyRecord();
+    }
+    //清除正在播放的节ID
+		// this.$store.commit('setPlayObj',null)
+    this.$store.commit("setPlaySectionId", { playSectionId: 0 });
+    this.$store.commit("setPlayChannelId", { playChannelId: 0 });
+    this.$store.commit("setPlayVID", { playVID: null });
+    this.closePlv();
+    console.log("onUnload");
+    //移除所有的事件监听器
+    uni.$off();
+    clearInterval(this.answerTimer);
+    if (this.timer) {
+      clearInterval(this.timer);
+    }
+    // console.log(this.lockTimer, "this.lockTimer");
+    // if (this.lockTimer) {
+    //   clearInterval(this.lockTimer);
+    //   this.$api
+    //     .lockDelLock({
+    //       action: "jxjy",
+    //     })
+    //     .then((res) => {});
+    // }
+    // websocket.sendMsg("delAction");
+  },
+  mounted() {
+    uni.$on("changeSection", (oldSectionId) => {
+      console.log(this.playVID);
+				this.hasStart = false;
+      this.photoConfig = false;
+      this.photoIndex = 0;
+      var polyvPlayerContext = this.selectComponent("#playerVideo");
+      if (polyvPlayerContext) {
+        //解决同个节视频切换问题
+        polyvPlayerContext.seek(0);
+        polyvPlayerContext.pause();
+      }
+      //清除直播
+      this.$store.commit("setPlayChannelId", { playChannelId: 0 });
+      this.postStudyRecord(0, oldSectionId);
+    });
+    uni.$on("getSection", (item) => {
+      //清除直播
+				this.hasStart = false;
+      this.isPlayRebuild = item.rebuild;
+      this.photoConfig = false;
+      this.photoIndex = 0;
+      this.sectionItem = item;
+      this.$store.commit("setPlayChannelId", { playChannelId: 0 });
+      //获取拍照历史
+      this.getPhotoLastRecord();
+			this.polyvLiveHistoryChatMsgList();
+      this.playVideo(item);
+    });
+    uni.$on("levelId", (item) => {
+      let arr = item.split("-");
+      //点击节获取的各层级ID
+      this.moduleId = arr[0];
+      this.chapterId = arr[1];
+    });
+    uni.$on("getChannel", (item) => {
+      //清除录播
+				this.hasStart = false;
+      this.$store.commit("setPlayVID", { playVID: null });
+      this.getPhotoLastRecord();
+      this.playChannel(item);
+			this.channelItem = item;
+    });
+    uni.$on("isRebuild", (item) => {
+      console.log(item);
+      this.isRebuild = item;
+    });
+    this.updateChapterOpen(true);
+  },
+  methods: {
+    ...mapMutations(["updateChapterOpen","updateLiveLast"]),
+		/**
+		 * 获取上次观看的直播
+		 */
+		studyRecordGetLastLive() {
+			this.$api.studyRecordGetLastLive({
+				orderGoodsId:this.orderGoodsId,
+				courseId:this.courseId
+			}).then(res => {
+				console.log(res,'liveres')
+				this.updateLiveLast(res.data.data)
+			})
+		},
+		/**
+		 * 获取最后一次看的节
+		 */
+		studyRecordQueryLiveLast() {
+			this.$api.studyRecordQueryLiveLast({
+				orderGoodsId:this.orderGoodsId,
+				courseId:this.courseId
+			}).then(res => {
+				console.log(res,'couse')
+				if(res.data.data) {
+					if(res.data.data.sectionType == 1) { //录播
+					this.$store.commit("setPlaySectionId", { playSectionId: res.data.data.sectionId });
+					this.$store.commit("setPlayVID", { playVID: res.data.data.recordingUrl });
+					this.sectionItem = res.data.data;
+						this.playVideo(res.data.data)
+					} else if(res.data.data.sectionType == 2) { //直播
+						this.studyRecordGetLastLive();
+					} else if(res.data.data.sectionType == 3) { //回放
+					this.$store.commit("setPlaySectionId", { playSectionId: res.data.data.sectionId });
+					this.$store.commit("setPlayVID", { playVID: res.data.data.recordingUrl });
+						this.sectionItem = res.data.data;
+						this.polyvLiveHistoryChatMsgList();
+						this.playVideo(res.data.data)
+					}
+					
+				}
+			})
+		},
+    goLive(item) {
+			let moduleId = item.moduleId || 0;
+			let chapterId = item.chapterId || 0;
+			let sectionId = item.sectionId || item.menuId;
+			let encode = encodeURIComponent(WEBVIEW_URL+'pages/live/index?token='+uni.getStorageSync('token')+'&userInfo='+JSON.stringify(this.userInfo)+'&channelId='+item.liveUrl+'&gradeId='+this.gradeId+'&courseId='+this.courseId+'&goodsId='+this.goodsId+'&orderGoodsId='+this.orderGoodsId+'&sectionId='+sectionId+'&chapterId='+chapterId+'&moduleId='+moduleId)
+			uni.navigateTo({
+				url:`../../pages/webview/index?url=`+encode
+			})
+		},
+		studyRecordMenuAllList() {
+			this.$api.studyRecordMenuAllList({
+				courseId:this.courseId,
+				gradeId:this.gradeId,
+				goodsId:this.goodsId
+			}).then(res => {
+				let nowTime = Number(new  Date().getTime()/1000).toFixed(0)
+				// this.livingItem = res.data.data[0]
+				this.livingItem = res.data.data.find(item => item.liveStartTime<=nowTime&&item.liveEndTime>nowTime);
+			})
+		},
+		polyvLiveHistoryChatMsgList() {
+			this.$api.polyvLiveHistoryChatMsgList({
+				sectionId:this.playSectionId,
+				channelId:this.sectionItem.liveUrl
+			}).then(res => {
+				this.historyChatMsgList = res.data.data
+			})
+		},
+		
+    /**
+     * 获取业务层次详情
+     */
+    // courseBusiness() {
+    //   this.$api.courseBusiness(this.goodsData.businessId).then((res) => {
+    //     this.businessData = res.data.data;
+    //   });
+    // },
+    /**
+     * 计算tabs宽度
+     */
+    itemWidth() {
+      return 100 / this.list.length + "%";
+    },
+    /**
+     * 获取讲义权限
+     */
+    // courseHandouts() {
+    //   this.$api.courseHandouts(this.goodsData.handoutsId).then((res) => {
+    //     this.courseHandoutsData = res.data.data;
+    //   });
+    // },
+    findMenuNextSection(index) {
+      for (let i = index + 1; i < this.reMenuList.length; i++) {
+        let item = this.reMenuList[i];
+        if (item.type == 3) {
+          return item;
+        }
+      }
+      return {};
+    },
+		loadedmetadata(e) {
+			var polyvPlayerContext = this.selectComponent("#playerVideo");
+			this.hasStart = true;
+			uni.$off('playPause')
+			uni.$on('playPause',() => {
+				polyvPlayerContext.pause()
+			})
+			if(!this.recordObj.videoCurrentTime) { //新视频直接提交一条观看记录
+				this.postStudyRecord(0)
+			}
+		},
+    getPhotoLastRecord() {
+      let self = this;
+      let data = {
+        sectionId: parseInt(self.playSectionId),
+        goodsId: parseInt(self.goodsId),
+        courseId: parseInt(self.courseId),
+        gradeId: parseInt(self.gradeId),
+        chapterId: parseInt(self.chapterId),
+        moduleId: parseInt(self.moduleId),
+				orderGoodsId: this.orderGoodsId,
+      };
+      this.$api.getPhotoLastRecord(data).then((res) => {
+        if (res.data.code == 200) {
+          //清空历史数据
+          self.photoHistoryList = [];
+          this.photoIndex = 0;
+          self.photoList = [];
+          for (let i = 0; i < res.data.data.length; i++) {
+            //-2存储随机拍照数组
+            if (res.data.data[i].photoIndex == -2) {
+              self.photoList = res.data.data[i].timeInterval.split(",");
+            } else {
+              self.photoHistoryList.push(res.data.data[i].photoIndex);
+            }
+          }
+        }
+      });
+    },
+    //postTime 只提交随机时间
+    postCoursePhotoRecord(postTime = false) {
+      return new Promise((resolve, reject) => {
+        let currentTime = 0;
+        var polyvPlayerContext = this.selectComponent("#playerVideo");
+        if (polyvPlayerContext) {
+          currentTime = polyvPlayerContext.getCurrentTime();
+        }
+        let self = this;
+        let photoIndex = self.photoIndex;
+        let data = {
+          photo: self.ossAvatarUrl,
+          sectionId: parseInt(self.playSectionId),
+          goodsId: parseInt(self.goodsId),
+          courseId: parseInt(self.courseId),
+          photoTime: parseInt(currentTime > 0 ? currentTime : 0),
+          gradeId: parseInt(self.gradeId),
+          photoIndex: postTime ? -2 : parseInt(photoIndex), //从0算起,-2只提交随机时间
+          photoNum: parseInt(self.photoNum),
+          chapterId: parseInt(self.chapterId),
+          moduleId: parseInt(self.moduleId),
+          timeInterval: postTime ? self.photoList.join(",") : "",
+					orderGoodsId: this.orderGoodsId,
+        };
+        console.log("提交接口", data);
+        this.$api
+          .coursePhotoRecord(data)
+          .then((res) => {
+						console.log(res,'postCoursePhotoRecord')
+            if (res.data.code == 200) {
+              resolve();
+            } else {
+              reject();
+            }
+          })
+          .catch((err) => {
+            reject();
+          });
+      });
+    },
+    randomNum(minNum, maxNum) {
+      switch (arguments.length) {
+        case 1:
+          return parseInt(Math.random() * minNum + 1, 10);
+          break;
+        case 2:
+          return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10);
+          break;
+        default:
+          return 0;
+          break;
+      }
+    },
+    //配置随机拍照时间
+    configPhoto() {
+      var polyvPlayerContext = this.selectComponent("#playerVideo");
+      let totalVideoTime = polyvPlayerContext.getDuration();
+      let duration = polyvPlayerContext.getCurrentTime();
+      let photoNum = this.photoNum;
+      if (!this.photoConfig) {
+        this.photoConfig = true;
+        // let  spaceTime = Math.floor(totalVideoTime/photoNum) //拍照时间区间
+        // if(spaceTime<5){//区间小于5秒
+        // 	photoNum = Math.floor(totalVideoTime/5)
+        // 	spaceTime = 5
+        // }
+        // if(photoNum<1){
+        // 	photoNum = 1 //只要设置,至少拍一次
+        // 	spaceTime = totalVideoTime
+        // }
+        // let initSpace = 0
+        //没有历史拍照间隔数据
+        if (this.photoList.length == 0) {
+          if (totalVideoTime >= 900) {
+            //大于15分钟
+            if (photoNum == 1) {
+              //开头拍1张
+              this.photoList.push(0);
+            } else if (photoNum == 3) {
+              //拍3张
+              this.photoList.push(0); //开头拍一张
+              let centerTime = Math.floor(totalVideoTime / 2); //获取中间时间
+              let centerMinTime = centerTime - 300; //前后5分钟
+              let centerMaxTime = centerTime + 300;
+              let centerTakeTime = this.randomNum(centerMinTime, centerMaxTime);
+              this.photoList.push(centerTakeTime); //中间拍一张
+              let endMaxTime = totalVideoTime - 60;
+              let endMinTime = totalVideoTime - 300;
+              let endTakeTime = this.randomNum(endMinTime, endMaxTime);
+              this.photoList.push(endTakeTime); //最后拍一张
+            }
+          } else {
+            //小于15分钟,只拍前后各一张
+            if (photoNum == 1) {
+              //开头拍1张
+              this.photoList.push(0);
+            } else if (photoNum == 3) {
+              //拍2张
+              if (totalVideoTime <= 300) {
+                //小于5分钟
+                this.photoList.push(0); //开头拍一张
+                let endTakeTime = this.randomNum(10, totalVideoTime); //中间随机取一张
+                this.photoList.push(endTakeTime);
+              } else {
+                this.photoList.push(0); //开头拍一张
+                let endMaxTime = totalVideoTime - 60;
+                let endMinTime = totalVideoTime - 300;
+                let endTakeTime = this.randomNum(endMinTime, endMaxTime);
+                this.photoList.push(endTakeTime); //最后1-5分钟拍一张
+              }
+            }
+          }
+          // for(let i=0;i<photoNum;i++){
+          // 	let s = this.randomNum(initSpace,initSpace+spaceTime)
+          // 	if(s>totalVideoTime){
+          // 		s = totalVideoTime-1
+          // 	}
+          // 	if(s<=5){
+          // 		s =5 //避免出现5秒内拍照时间
+          // 	}
+          // 	this.photoList.push(s)
+          // 	initSpace+=spaceTime
+          // }
+          console.log(this.photoList, "随机拍照时间数组11", photoNum);
+          this.postCoursePhotoRecord(true); //提交随机拍照时间数组
+        }
+        console.log(this.photoList, "随机拍照时间数组");
+        //兼容已有观看历史
+        for (let i = 0; i < this.photoList.length - 1; i++) {
+          if (
+            this.photoList[i] < duration &&
+            this.photoList[i + 1] > duration
+          ) {
+            this.photoIndex = i + 1;
+            //				console.log("我的修改了photoIndex")
+            break;
+          }
+          if (duration > this.photoList[this.photoList.length - 1]) {
+            this.photoIndex = this.photoList.length - 1; //取最后一个下标
+            //				console.log("我的修改了photoIndex")
+            break;
+          }
+        }
+      }
+    },
+    getLiveUid(channelId) {
+      let self = this;
+      return new Promise((resolve) => {
+        let data = {
+          channelId: channelId,
+					orderGoodsId: this.orderGoodsId,
+        };
+        self.$api.polyvSign(data).then((res) => {
+          resolve(res.data.data);
+        });
+      });
+    },
+    timeEventLiving() {
+      if (plv != null) {
+        if (this.livePlay) {
+          this.liveDuration = this.liveDuration + 1; //每隔1秒
+          if (this.liveDuration == 2) {
+            //直播第2秒拍照
+						console.log(this.channelItem)
+						console.log(this.photoHistoryList,'this.photoHistoryList')
+            if (
+              this.goodsPhotographConfig && this.goodsPhotographConfig.livephotograph == 1 &&
+              this.channelItem.learning != 1 && this.photoHistoryList.length == 0
+            ) {
+              //开启直播拍照
+              this.openPhoto();
+            } else {
+							this.postStudyRecord(0);
+						}
+          }
+        }
+      }
+    },
+    playerLiveStatusChange(e) {
+      const status = e.detail.status;
+      console.log("直播状态", status);
+      if (status === "live") {
+        console.log("开始直播");
+        //开始播放
+        if (this.timer) {
+          clearInterval(this.timer);
+        }
+        this.livePlay = true;
+        this.timer = setInterval(this.timeEventLiving, 1000); //定时器
+      }
+      if (status === "end") {
+				this.hasStart = false;
+        if (this.livePlay) {
+          //只有播放过的结束才提交,避免未开播触发结束
+          this.postStudyRecord(1);
+        }
+        console.log("结束直播");
+        this.livePlay = false;
+        // 未开始
+      }
+    },
+    closePlv() {
+      if (plv) {
+        plv.destroy();
+      }
+    },
+    playChannel(item) {
+      if (this.timer) {
+        clearInterval(this.timer);
+      }
+      this.startStatus = true;
+      this.initLive();
+    },
+    setLiveOption(status) {
+      const { userId, channelId, recordFileSimpleModel, playbackEnabled } =
+        this.detail;
+      const playRecordFile =
+        playbackEnabled && recordFileSimpleModel && status === "end";
+			
+			// if(this.channelItem.sectionType == 3) { //回放
+				
+			// 	// this.videoOption = {
+			// 	//   mode: "live",
+			// 	//   uid: this.liveObj.uid, //this.playChannelId  egsxlptzdq
+			// 	//   cid: this.playChannelId,
+			// 	//   openId: this.userInfo.userAccount,
+			// 	//   isAutoChange: false,
+			// 	//   forceVideo: false,
+			// 	// };
+			// } else {  //直播
+				
+				this.videoOption = {
+				  mode: "live",
+				  uid: this.liveObj.uid, //this.playChannelId  egsxlptzdq
+				  cid: this.playChannelId,
+				  openId: this.userInfo.userAccount,
+				  isAutoChange: false,
+				  forceVideo: false,
+				};
+			// }
+    },
+    async initLive() {
+      console.log(this.playChannelId, 7111);
+      this.liveObj = await this.getLiveUid(this.playChannelId);
+      this.initLiveOk = true;
+      let optionsData = {};
+      optionsData.mode = "live";
+      optionsData.forceVideo = false;
+      optionsData.channelId = this.playChannelId; // 频道ID '2553128'
+      optionsData.openId = this.userInfo.userAccount; // 用户openId  this.userInfo.userAccount 'oQ5eX5BCtSjkE1ct8CzvxGWgh0hQ'
+      optionsData.userId = this.liveObj.uid; // 2.0.0及以上版本的demo需要使用 userId 设置学员唯一id 'egsxlptzdq'
+      let self = this;
+      this.closePlv();
+      plv.init(optionsData).then(({ detail, chat }) => {
+        self.liveDetail = detail;
+
+        // 设置mode为live的videoOption
+        this.setLiveOption();
+        if (detail.isPPT) {
+          chat.on(chat.events.SLICESTART, () => {
+            // 开始直播
+          });
+        } else {
+          plv.api.getOrdinaryLiveStatus(detail.stream);
+        }
+      });
+    },
+    openSetting(res) {
+      console.log(res, 98);
+    },
+    getCameraSetting() {
+      const self = this;
+      wx.getSetting({
+        success: (res) => {
+          if (res.authSetting["scope.camera"]) {
+            // 用户已经授权
+            self.showSet = false;
+          } else {
+            // 用户还没有授权,向用户发起授权请求
+            wx.authorize({
+              scope: "scope.camera",
+              success() {
+                // 用户同意授权
+                self.showSet = false;
+              },
+              fail() {
+                // 用户不同意授权
+                self.showSet = true;
+                /* wx.showToast({
+		                title: '摄像头授权失败',
+		                icon: 'none',
+		                duration: 3000
+		              }) */
+              },
+            });
+          }
+        },
+        fail: (res) => {},
+      });
+    },
+    studyNotice() {
+      this.noticeShow = true;
+    },
+    //播放笔记视频
+    async playNoteVideo(item) {
+      console.log(item, "noteItem");
+      if (this.timer) {
+        clearInterval(this.timer);
+      }
+      if (this.vid) {
+        //切换视频
+        var polyvPlayerContext = this.selectComponent("#playerVideo");
+        polyvPlayerContext.changeVid(item.recordingUrl);
+      } else {
+        this.vid = item.recordingUrl;
+      }
+      this.recordObj = { videoCurrentTime: item.noteSecond };
+      if (this.recordObj.videoCurrentTime) {
+        this.needSeek = true; //需要跳转到播放记录
+      }
+      this.startStatus = true;
+      //获取节笔记
+      this.getNoteList();
+    },
+    //正常播放视频
+    async playVideo(item) {
+      console.log(item);
+      if (this.timer) {
+        clearInterval(this.timer);
+      }
+      if (this.vid) {
+        //切换视频
+        var polyvPlayerContext = this.selectComponent("#playerVideo");
+        polyvPlayerContext.changeVid(item.recordingUrl);
+      } else {
+				console.log(2)
+        this.vid = item.recordingUrl;
+				
+      }
+      this.recordObj = null;
+      this.recordObj = await this.getRecordLast();
+      this.needSeek = true; //跳转到播放记录
+      this.startStatus = true;
+
+      //获取节笔记
+      this.getNoteList();
+    },
+    getRecordLast() {
+      let self = this;
+      return new Promise((resolve) => {
+        let data = {
+          gradeId: Number(self.gradeId),
+          goodsId: Number(self.goodsId),
+          sectionId: Number(self.playSectionId),
+          courseId: Number(self.courseId),
+          chapterId: parseInt(self.chapterId),
+          moduleId: parseInt(self.moduleId),
+					orderGoodsId: this.orderGoodsId,
+        };
+        self.$api.recordLast(data).then((res) => {
+          resolve(res.data.data);
+        });
+      });
+    },
+
+    jumpNote(item) {
+      this.noteId = item.noteId;
+      //没视频播放
+      if (this.playSectionId == 0) {
+        console.log("即将跳到笔记位置1");
+        this.$u.toast("即将跳到笔记位置");
+        this.$store.commit("setPlaySectionId", {
+          playSectionId: item.sectionId,
+        });
+        this.$store.commit("setPlayVID", { playVID: item.recordingUrl });
+        this.playNoteVideo(item);
+      } else {
+        //正在看当前笔记视频
+        console.log("即将跳到笔记位置2");
+        this.$u.toast("即将跳到笔记位置");
+        //跳到笔记时刻
+        var polyvPlayerContext = this.selectComponent("#playerVideo");
+        polyvPlayerContext.seek(item.noteSecond);
+        polyvPlayerContext.play();
+      }
+    },
+    postNote() {
+      let self = this;
+      if (!(this.playSectionId > 0)) {
+        this.$u.toast("目前无播放视频");
+        return;
+      }
+      if (!this.noteValue) {
+        this.$u.toast("请输入内容");
+        return;
+      }
+      if (!this.gradeId) {
+        this.$u.toast("暂无班级数据");
+        return;
+      }
+      var polyvPlayerContext = this.selectComponent("#playerVideo");
+      let noteDate = this.$method.getZeroTime();
+      let noteSecond = polyvPlayerContext.getCurrentTime();
+      console.log(noteSecond, 698);
+      if (!noteSecond) {
+        if (noteSecond == 0) {
+          //播放结束
+          noteSecond = polyvPlayerContext.getDuration();
+          console.log(noteSecond, 63398);
+        }
+        if (!noteSecond) {
+          this.$u.toast("视频暂未开始");
+          return;
+        }
+      }
+      let data = {
+        gradeId: this.gradeId,
+        goodsId: this.goodsId,
+        sectionId: this.playSectionId,
+        courseId: this.courseId,
+        noteText: this.noteValue,
+        noteDate: noteDate,
+        noteSecond: noteSecond,
+				orderGoodsId: this.orderGoodsId,
+      };
+      this.$api.postNote(data).then((res) => {
+        if (res.data.code == 200) {
+          this.$u.toast("发布成功");
+          self.getNoteList();
+          this.noteValue = "";
+        }
+      });
+    },
+    
+    getNoteList() {
+      let self = this;
+      self.noteList = [];
+      let data = {
+        courseId: this.courseId,
+        gradeId: this.gradeId,
+        goodsId: this.goodsId,
+				orderGoodsId: this.orderGoodsId,
+      };
+      if (this.playSectionId > 0) {
+        data.sectionId = this.playSectionId;
+      }
+      this.$api.noteList(data).then((res) => {
+        if (res.data.code == 200) {
+          self.noteList = res.data.rows;
+        }
+      });
+    },
+    delAnswer(answerId) {
+      let self = this;
+      let data = { answerId: answerId, status: -1 ,orderGoodsId: this.orderGoodsId,};
+      this.$api.delAnswer(data).then((res) => {
+        if (res.data.code == 200) {
+          self.getAnswerList();
+        }
+      });
+    },
+    clearCtx() {
+      console.log(4234);
+      this.placeholder = "您可以在这里输入答疑内容";
+      this.ctxValue = "";
+      this.assignUserId = 0;
+    },
+		blur() {
+			this.clearTimer = setTimeout(() => {
+				this.ctxValue = ""
+				this.isFocus = false;
+				this.assignUserId = 0;
+				this.placeholder = '您可以在这里输入答疑内容';
+			},2000)
+		},
+    replyContent(item) {
+			this.isFocus = true;
+      this.assignUserId = item.userId;
+      this.placeholder = "@" + item.realname;
+    },
+    delContent(item) {
+      this.delAnswer(item.answerId);
+    },
+    postAnswer() {
+      let self = this;
+      let data = {
+        courseId: this.courseId,
+        answerText: this.ctxValue,
+        goodsId: this.goodsId,
+				orderGoodsId: this.orderGoodsId,
+      };
+      if (this.assignUserId > 0) {
+        data.assignUserId = this.assignUserId;
+      }
+      this.$api.postAnswer(data).then((res) => {
+        if (res.data.code == 200) {
+          this.$u.toast("发布成功");
+          self.getAnswerList();
+					this.isFocus = false;
+          this.placeholder = "您可以在这里输入答疑内容";
+          this.ctxValue = "";
+          this.assignUserId = 0;
+        }
+      });
+    },
+    postContent() {
+      if (!this.ctxValue || this.ctxValue == "") {
+        this.$u.toast("请输入内容");
+        return;
+      }
+      this.postAnswer();
+    },
+    postStudyRecord(status = 0, sectionId = this.playSectionId) {
+      console.log("status", status);
+      let currentTime = 0;
+      let PlayDuration = 0;
+      var polyvPlayerContext = this.selectComponent("#playerVideo");
+      if (polyvPlayerContext) {
+        currentTime = polyvPlayerContext.getCurrentTime(); //总的视频播放时刻
+        PlayDuration = polyvPlayerContext.getVideoPlayDuration(); //本次看的时长
+      }
+      if (this.playChannelId > 0) {
+        currentTime = 2; //直播无法获取,无论开始结束都传2秒
+      }
+      let self = this;
+      let data = {
+        photo: self.ossAvatarUrl,
+        sectionId: parseInt(sectionId),
+        goodsId: parseInt(self.goodsId),
+        courseId: parseInt(self.courseId),
+				orderGoodsId: this.orderGoodsId,
+        studyDuration: parseInt(
+          PlayDuration > 0 ? PlayDuration : self.studyDuration
+        ),
+        gradeId: parseInt(self.gradeId),
+        chapterId: parseInt(self.chapterId),
+        moduleId: parseInt(self.moduleId),
+        videoCurrentTime: parseInt(
+          currentTime > 0 ? currentTime : self.studyDuration
+        ),
+      };
+      if (status > 0) {
+        console.log(sectionId, "sectionId");
+        data.status = status;
+      }
+      console.log("提交接口", data);
+      this.$api.studyRecord(data).then((res) => {
+        if (res.data.code == 200) {
+          if (status > 0) {
+            let moduleId = this.moduleId || 0;
+            let chapterId = this.chapterId || 0;
+            let playNextIdisRebuild = `moduleId${moduleId}chapterId${chapterId}sectionId${sectionId}isRebuild`;
+            let playNextId = `moduleId${moduleId}chapterId${chapterId}sectionId${sectionId}`; //拼接对应章节唯一id
+            console.log(playNextId, "playNextId");
+            console.log(playNextIdisRebuild, "playNextIdisRebuild");
+
+            uni.$emit("playNext" + playNextIdisRebuild, {
+              fromRebuild: this.isRebuild,
+            }); //通知播放结束,不来自重修目录的点击不用弹窗学习下一节
+            uni.$emit("playNext" + playNextId); //通知播放结束
+          }
+
+          self.ossAvatarUrl = "";
+        } else {
+          this.uploadLock = false;
+          uni.showToast({
+            icon: "none",
+            title: res.data.msg,
+          });
+        }
+        console.log(res, "res");
+      });
+    },
+    uploadFile(options, int) {
+			console.log(options)
+      var self = this;
+      return new Promise((resolve, reject) => {
+        var data = {
+          imageStatus: int,
+          gradeId: this.gradeId,
+					orderGoodsId: this.orderGoodsId,
+        };
+        self.$api.aliyunpolicy(data).then((res) => {
+          if (res.data.code != 200) {
+            self.$method.showToast("签名错误" + JSON.stringify(res.data));
+            return;
+          }
+          var ossToken = res.data.data.resultContent;
+          if (ossToken.host == null || ossToken.host == undefined) {
+            self.$method.showToast("上传路径报错" + JSON.stringify(res.data));
+            return;
+          }
+          uni.uploadFile({
+            url: ossToken.host,
+            name: "file",
+            filePath: options,
+            fileType: "image",
+            header: {
+              AuthorizationToken: "WX " + uni.getStorageSync("token"),
+            },
+            formData: {
+              key: ossToken.dir,
+              OSSAccessKeyId: ossToken.accessid,
+              policy: ossToken.policy,
+              Signature: ossToken.signature,
+              callback: ossToken.callback,
+              success_action_status: 200,
+            },
+            success: (result) => {
+              if (result.statusCode === 200) {
+                self.ossAvatarUrl = ossToken.dir;
+                resolve();
+              } else {
+                uni.showToast({
+                  title: "上传失败",
+                  icon: "none",
+                });
+                this.openPhoto();
+                return;
+              }
+            },
+            fail: (error) => {
+              uni.showToast({
+                title: "上传接口报错,请重新拍照上传" + error,
+                icon: "none",
+              });
+              this.openPhoto();
+              return;
+            },
+          });
+        });
+      });
+    },
+    imageInfos() {
+      var self = this;
+      return new Promise((resolve, reject) => {
+        uni.getImageInfo({
+          src: self.avatarUrl,
+          success: async (res) => {
+            let canvasWidth = res.width; //图片原始长宽
+            let canvasHeight = res.height;
+            if (canvasWidth > 2000 || canvasHeight > 2000) {
+              uni.compressImage({
+                src: self.avatarUrl,
+                quality: 75,
+                width: "35%",
+                height: "35%",
+                success: async (rest) => {
+                  const waitUpload = await self.uploadFile(
+                    rest.tempFilePath,
+                    0
+                  );
+                  resolve(waitUpload);
+                },
+              });
+            } else if (canvasWidth > 1000 || canvasHeight > 1000) {
+              uni.compressImage({
+                src: self.avatarUrl,
+                quality: 75,
+                width: "50%",
+                height: "50%",
+                success: async (rest) => {
+                  const waitUpload = await self.uploadFile(
+                    rest.tempFilePath,
+                    0
+                  );
+                  resolve(waitUpload);
+                },
+              });
+            } else {
+              console.log("无需压缩");
+              const waitUpload = await self.uploadFile(self.avatarUrl, 0);
+              resolve(waitUpload);
+            }
+          },
+        });
+      });
+    },
+    timeEvent() {
+      let self = this;
+      var polyvPlayerContext = this.selectComponent("#playerVideo");
+      if (polyvPlayerContext != null) {
+        this.playTime = polyvPlayerContext.getCurrentTime(); //播放时刻
+        //	console.log(this.playTime,789,this.photoHistoryList)
+        //判断是否需要拍照
+        if (this.photoNum > 0) {
+          this.configPhoto();
+          let photoTime = 0; //获取拍照秒数
+          for (let i = 0; i < this.photoList.length; i++) {
+            photoTime = Number(this.photoList[i]); //获取拍照秒数
+            if (photoTime < this.playTime && photoTime > this.playTime - 8) {
+              //3秒区间内才触发拍照,避免拉动滚动条
+              if (
+                this.photoHistoryList.indexOf(i) < 0 &&
+                this.sectionItem.learning != 1
+              ) {
+                //不存在拍照历史,没有重修过,没有学过,则拍照
+                //启动拍照
+                //暂停
+                polyvPlayerContext.exitFullScreen();
+                polyvPlayerContext.pause();
+                this.photoIndex = i;
+                this.openPhoto();
+              }
+            }
+          }
+        }
+      }
+    },
+    closeToast() {
+      clearTimeout(this.toastTimer);
+      this.videoToastShow = false;
+    },
+    restart() {
+      var polyvPlayerContext = this.selectComponent("#playerVideo");
+      polyvPlayerContext.seek(0);
+      console.log("seek1");
+      clearTimeout(this.toastTimer);
+      this.videoToastShow = false;
+    },
+    onStateChange(newstate, oldstate) {
+      if (newstate.detail.newstate == "playing") {
+        if (this.needSeek) {
+          var polyvPlayerContext = this.selectComponent("#playerVideo");
+          if (this.recordObj.videoCurrentTime) {
+            console.log("seek2");
+            polyvPlayerContext.seek(this.recordObj.videoCurrentTime);
+            this.seekTime = this.$method.secondToDate(
+              this.recordObj.videoCurrentTime
+            );
+            this.videoToastShow = true;
+            this.toastTimer = setTimeout(() => {
+              this.videoToastShow = false;
+            }, 3000);
+          } else {
+            polyvPlayerContext.seek(1); //避免相同节继续播放
+            console.log("seek3");
+          }
+
+          polyvPlayerContext.play();
+          this.needSeek = false;
+        }
+        //开始播放
+        if (this.timer) {
+          clearInterval(this.timer);
+        }
+        this.timer = setInterval(this.timeEvent, 1000); //定时器
+      }
+      if (newstate.detail.newstate == "pause") {
+        clearInterval(this.timer);
+        //暂停提交记录
+        /* this.ossAvatarUrl = ""
+				this.postStudyRecord() */
+      }
+      if (newstate.detail.newstate == "ended") {
+        clearInterval(this.timer);
+        uni.showToast({
+          icon: "none",
+          title: "播放完毕",
+        });
+				this.hasStart = false;
+        this.postStudyRecord(1);
+        // uni.$emit('playNext') //播放重修下一节
+      }
+    },
+    //拍照
+    openPhoto() {
+      var polyvPlayerContext = this.selectComponent("#playerVideo");
+      if (polyvPlayerContext) {
+        polyvPlayerContext.exitFullScreen();
+      }
+
+      this.enableAutoRotation = false;
+      this.photoPopup = true;
+      this.isTaking = true;
+      uni.setKeepScreenOn({
+        keepScreenOn: true,
+      });
+      uni.authorize({
+        scope: "scope.camera",
+        success() {},
+      });
+    },
+    /**
+     * 人脸匹配
+     */
+    faceRecognition() {
+      return new Promise((resolve) => {
+        let fileSystem = uni.getFileSystemManager();
+        fileSystem.readFile({
+          filePath: `${this.avatarUrl}`,
+          encoding: "base64",
+          position: 0,
+          success: (res) => {
+            console.log(res);
+            let base64 = "data:image/jpg;base64," + res.data;
+						console.log({
+                imageA: base64,
+                orderGoodsId: this.orderGoodsId,
+                gradeId: this.gradeId,
+              },'base64Data')
+            this.$api
+              .faceCertificationCompareFace({
+                imageA: base64,
+                orderGoodsId: this.orderGoodsId,
+                gradeId: this.gradeId,
+              })
+              .then((res) => {
+                console.log(res, "res");
+                resolve(res.data.data);
+              });
+          },
+          fail(err) {
+            console.error(err, "err");
+          },
+        });
+      });
+    },
+
+    async submit() {
+      if (this.uploadLock) {
+        return;
+      }
+      this.uploadLock = true;
+
+      let compareFaceData = await this.faceRecognition();
+			console.log(compareFaceData,'compareFaceData')
+      if (compareFaceData >= 80) {
+        const waitYS = await this.imageInfos();
+        this.postCoursePhotoRecord()
+          .then((res) => {
+            this.photoHistoryList.push(this.photoIndex);
+            this.postStudyRecord(); //提交记录
+            //恢复播放
+
+            uni.setKeepScreenOn({
+              keepScreenOn: false,
+            });
+            this.photoPopup = false;
+            this.uploadLock = false;
+            this.enableAutoRotation = true;
+            var polyvPlayerContext = this.selectComponent("#playerVideo");
+            if (polyvPlayerContext != null) {
+              polyvPlayerContext.play();
+            }
+          })
+          .catch((err) => {
+            uni.showToast({
+              title: "上传接口报错,请重新拍照上传" + err,
+              icon: "none",
+            });
+            this.uploadLock = false;
+            this.openPhoto();
+          });
+      } else {
+				uni.showToast({
+				  title: "人脸匹配不通过,请重新拍照上传",
+				  icon: "none",
+				  duration: 2000,
+				});
+				
+				setTimeout(() => {
+				  this.uploadLock = false;
+				  this.openPhoto();
+				}, 2000);
+				return;
+			}
+    },
+    reTake() {
+      this.isTaking = true;
+    },
+    //确认拍照
+    takePhoto() {
+      var self = this;
+      const ctx = uni.createCameraContext();
+      ctx.takePhoto({
+        quality: "high",
+        success: (res) => {
+          console.log(res.tempImagePath);
+          self.avatarUrl = res.tempImagePath;
+          this.isTaking = false;
+          // self.submit();
+
+          // self.photoPopup = false;
+          // self.enableAutoRotation = true;
+        },
+        fail: (err) => {
+          console.log(err);
+        },
+      });
+    },
+    playError(e) {
+      console.log(e);
+    },
+    //拍照报错
+    error(e) {
+      console.log(e.detail);
+    },
+    //关闭相机
+    closePhoto() {
+      this.photoPopup = false;
+      self.enableAutoRotation = true;
+    },
+    /**
+     * 进入全屏
+     */
+    fullscreenchange(event) {
+      console.log(event);
+      if (event.detail.direction == "vertical") {
+        this.navShow = true;
+      } else if (event.detail.direction == "horizontal") {
+        this.navShow = false;
+      }
+    },
+    getGoodsDetail() {
+      let self = this;
+      this.$api.goodsDetail(this.goodsId).then((res) => {
+        self.goodsData = res.data.data;
+        console.log(self.gradeId, "班级ID");
+        // this.courseBusiness();
+        // this.courseHandouts();
+        self.getMenuList();
+				console.log(self.goodsData,'self.goodsData')
+        //获取节笔记
+        this.getNoteList();
+        if (self.goodsData.goodsPlayConfig) {
+          self.goodsPlayConfig = JSON.parse(self.goodsData.goodsPlayConfig);
+          if (self.goodsPlayConfig.autoPlay > 0) {
+            self.autoplay = true;
+          }
+          if (self.goodsPlayConfig.drag > 0) {
+            self.isAllowSeek = "yes";
+          }
+          if (self.goodsPlayConfig.speed > 0) {
+            self.playbackRate = [0.5, 0.8, 1.0, 1.25, 1.5, 2.0];
+          }
+        }
+        if (self.goodsData.goodsPhotographConfig) {
+          self.goodsPhotographConfig = JSON.parse(
+            self.goodsData.goodsPhotographConfig
+          );
+          if (self.goodsPhotographConfig.photoNum > 0) {
+            self.photoNum = self.goodsPhotographConfig.photoNum;
+            console.log(self.photoNum, 777777);
+          }
+        }
+      });
+    },
+    startVideo() {
+      this.startStatus = true;
+    },
+    getAnswerList() {
+      let self = this;
+      this.$api
+        .answerList({ courseId: this.courseId, goodsId: this.goodsId,orderGoodsId: this.orderGoodsId, })
+        .then((res) => {
+          if (res.data.code == 200) {
+            self.answerList = res.data.rows;
+          }
+        });
+    },
+    getMenuList() {
+      let self = this;
+      this.$api
+        .reMenuList({ courseId: this.courseId, gradeId: this.gradeId,orderGoodsId: this.orderGoodsId, })
+        .then((res) => {
+          if (res.data.code == 200) {
+            for (let i = 0; i < res.data.rows.length; i++) {
+              let item = res.data.rows[i];
+              item.down = true;
+              item.id = item.menuId;
+              item.name = item.menuName;
+              item.menuType = item.type;
+            }
+            self.menuList = res.data.rows;
+
+            for (let i = 0; i < res.data.rows.length; i++) {
+              if (res.data.rows[i].type == 1) {
+                this.menuIndex = [i];
+                break;
+              } else if (res.data.rows[i].type == 2) {
+                this.menuIndex = [i];
+                break;
+              }
+            }
+          }
+        });
+    },
+    courseDetail() {
+      let self = this;
+      this.$api.courseDetail(this.courseId).then((res) => {
+        if (res.data.code == 200) {
+          if (res.data.data.educationName == "继续教育") {
+            // this.$api
+            //   .lockLockAction({
+            //     action: "jxjy",
+            //   })
+            //   .then((res) => {});
+            // this.lockTimer = setInterval(() => {
+            //   this.$api
+            //     .lockLockAction({
+            //       action: "jxjy",
+            //     })
+            //     .then((res) => {});
+            // }, 10000);
+
+            // websocket.sendMsg("doCourse");
+          }
+          self.detail = res.data.data;
+        }
+      });
+    },
+    open(item) {
+      item.showChildren = !item.showChildren;
+    },
+    change(index) {
+      this.current = index;
+    },
+    openDocument() {
+      let self = this;
+      let url = this.$method.splitImgHost(this.courseHandoutsData.handoutsUrl);
+      console.log(url);
+      uni.downloadFile({
+        url: url,
+        success: function (res) {
+          console.log(999);
+          var filePath = res.tempFilePath;
+          uni.openDocument({
+            filePath: filePath,
+            showMenu: self.courseHandoutsData.canDownload == 1 ? true : false,
+            success: function (res) {
+              console.log(res, "打开文档成功");
+            },
+            fail: function (err) {
+              console.log(err);
+              uni.showToast({
+                icon: "none",
+                title: "文档地址错误",
+              });
+            },
+          });
+        },
+        fail: (err) => {
+          uni.showModal({
+            title: "提示",
+            content: "文档错误," + err.errMsg,
+            showCancel: false,
+          });
+        },
+      });
+    },
+  },
+};
+</script>
+
+<style lang="scss" scope>
+.top {
+	&__header {
+		position:relative;
+		width:100%;
+		height:150rpx;
+		padding:24rpx 150rpx 24rpx 24rpx;
+		
+		.img {
+			position:absolute;
+			left:0;
+			top:0;
+			width:100%;
+		}
+		
+		.note {
+			position:relative;
+			z-index: 10;
+			font-size: 24rpx;
+			font-family: PingFang SC;
+			font-weight: bold;
+			color: #EFDBFF;
+		}
+		
+		.title {
+			position:relative;
+			z-index: 10;
+			font-size: 26rpx;
+			font-family: PingFang SC;
+			font-weight: bold;
+			color: #FFFFFF;
+		}
+		
+		.desc {
+			
+		}
+	}
+}
+.polyv_detail {
+  display: flex;
+  flex-direction: column;
+  height: 100vh;
+
+  .box {
+    flex: 1;
+    overflow: hidden;
+    margin: 20rpx;
+
+    .box_in {
+      height: 100%;
+    }
+  }
+}
+.btnSet {
+  width: 440rpx;
+  height: 80rpx;
+  background: #007aff;
+  border-radius: 40rpx;
+  color: #ffffff;
+  font-size: 28rpx;
+  line-height: 80rpx;
+}
+.btnReply {
+  width: 80rpx;
+  height: 40rpx;
+  background: #e3f0ff;
+  border-radius: 16rpx;
+  text-align: center;
+  color: #007aff;
+}
+.btnDel {
+  width: 80rpx;
+  height: 40rpx;
+  background: #ffedf0;
+  border-radius: 16rpx;
+  text-align: center;
+  color: #ff2d55;
+}
+.btnReply {
+  width: 80rpx;
+  height: 40rpx;
+  background: #e3f0ff;
+  border-radius: 16rpx;
+  font-size: 24rpx;
+}
+.lecture-box {
+  display: flex;
+  align-items: center;
+  height: 80rpx;
+  background: #ffffff;
+  border-radius: 16rpx 16rpx 16rpx 16rpx;
+
+  .title {
+    padding: 10rpx;
+    flex: 1;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    color: #333;
+    font-weight: bold;
+    font-size: 32rpx;
+  }
+
+  .btn {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    width: 80rpx;
+    height: 80rpx;
+    background: #ffffff;
+    box-shadow: -4rpx 0rpx 4rpx 0rpx rgba(0, 0, 0, 0.1);
+    border-radius: 16rpx 16rpx 16rpx 16rpx;
+  }
+}
+
+.lecture-content {
+  background: #fff;
+  margin-top: 10rpx;
+  padding: 10rpx;
+  border-radius: 16rpx;
+}
+.photoBox {
+  background-color: #ffffff;
+  border-radius: 32px 32px 0px 0px;
+  .photoTop {
+    height: 74rpx;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding: 0rpx 38rpx;
+    .sqzz {
+      width: 28rpx;
+      height: 28rpx;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+    }
+    .centersq {
+      color: #333;
+      font-size: 30rpx;
+      font-weight: 500;
+    }
+  }
+  .photoCenter {
+    width: 750rpx;
+    height: 979rpx;
+    position: relative;
+    .custom {
+      width: 750rpx;
+      height: 979rpx;
+      position: absolute;
+      z-index: 1000;
+      top: 0;
+      left: 0;
+      image {
+        width: 100%;
+        height: 100%;
+      }
+    }
+  }
+
+  .btns {
+    display: flex;
+
+    .btnResult {
+      height: 100rpx;
+      flex: 1;
+      background-color: #07c160;
+      text-align: center;
+      line-height: 100rpx;
+      color: #fff;
+      font-size: 32rpx;
+      font-weight: bold;
+    }
+  }
+}
+.chat_box {
+  display: flex;
+  padding: 20rpx;
+  justify-content: space-between;
+}
+.chat3 {
+  font-size: 30rpx;
+  font-family: PingFang SC;
+  font-weight: 500;
+  color: #666666;
+  margin-top: 10rpx;
+}
+.chat2 {
+  font-size: 20rpx;
+  font-family: PingFang SC;
+  font-weight: 500;
+  color: #999999;
+  margin-top: 10rpx;
+}
+.chat1 {
+  font-size: 24rpx;
+  font-family: PingFang SC;
+  font-weight: 500;
+  color: #333333;
+}
+.leftPadding {
+  margin-left: 8rpx;
+}
+.t2Content {
+  font-size: 28rpx;
+  font-family: PingFang SC;
+  font-weight: bold;
+  color: #999999;
+  line-height: 48rpx;
+}
+.tBox2 {
+  display: flex;
+  padding-top: 10rpx;
+  color: #333333;
+  font-size: 30rpx;
+}
+.tBox {
+  display: flex;
+  align-items: center;
+  padding-top: 10rpx;
+}
+.title {
+  font-size: 24rpx;
+  color: #999999;
+}
+
+page {
+  // padding-top: 10px;
+  // padding-top: constant(safe-area-inset-top);
+  // padding-top: env(safe-area-inset-top);
+}
+.inputBottom {
+  position: fixed;
+  left: 0;
+  bottom: 0;
+  background: #ffffff;
+  height: 98rpx;
+  display: flex;
+  align-items: center;
+  width: 100%;
+
+  .flex_auto {
+    flex: 1;
+    margin-left: 10%;
+
+    .input {
+      height: 60rpx;
+    }
+  }
+
+  .btn {
+    color: #007aff;
+    font-size: 30rpx;
+    font-weight: bold;
+    width: 15%;
+    text-align: center;
+  }
+}
+.noteBox {
+  width: 100%;
+  background: #ffffff;
+  padding: 10rpx;
+  border-radius: 16rpx;
+}
+.dateBox {
+  width: 216rpx;
+  height: 48rpx;
+  background: #ffffff;
+  border-radius: 24rpx;
+  font-size: 24rpx;
+  color: #666666;
+  text-align: center;
+  line-height: 48rpx;
+  margin: 20rpx 0;
+}
+.t_content1 {
+  color: #007aff;
+  margin-left: 10rpx;
+}
+.tag1 {
+  border: 2rpx solid #007aff;
+  border-radius: 8rpx;
+  font-size: 20rpx;
+  color: #007aff;
+  padding: 5rpx;
+}
+.b_title {
+  color: #333333;
+  font-size: 30rpx;
+  font-weight: bold;
+}
+page {
+  background: #eaeef1;
+}
+.menuBox {
+  width: 100%;
+  background: #ffffff;
+  border-radius: 16rpx;
+  padding: 20rpx;
+  margin-bottom: 20rpx;
+}
+.btnspric {
+  border-top: 1rpx solid #eee;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  height: 108rpx;
+  padding-left: 43rpx;
+  padding-right: 32rpx;
+}
+.btnspric > .lefprL {
+  font-size: 36rpx;
+  color: #0c141f;
+  font-weight: bold;
+}
+.btnspric > .lefprR {
+  padding: 0rpx 24rpx;
+  height: 60rpx;
+  line-height: 60rpx;
+  text-align: center;
+  color: #fff;
+  background: #32467b;
+  border-radius: 24rpx;
+  box-shadow: 0rpx 0rpx 16rpx 4rpx rgba(145, 156, 178, 0.1);
+}
+.yhj,
+.hdyhj {
+  padding: 24rpx 29rpx 24rpx 34rpx;
+}
+.yhj {
+  border-bottom: 16rpx solid #f9f9f9;
+}
+.yhjtit {
+  font-size: 30rpx;
+  color: #0c141f;
+  font-weight: 500;
+  margin-bottom: 14rpx;
+}
+.yhjList {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  margin-bottom: 14rpx;
+}
+.yhjList > .yhjLefts {
+  display: flex;
+  align-items: center;
+}
+.yhjLefts > .yhl {
+  color: #32467b;
+  font-size: 30rpx;
+  margin-right: 31rpx;
+}
+.yhjLefts > .yhbq {
+  font-size: 24rpx;
+  color: #ff9500;
+  border-radius: 18rpx;
+  background-color: rgba(255, 149, 0, 0.2);
+  border: 2rpx solid #ff9500;
+  height: 38rpx;
+  line-height: 38rpx;
+  padding: 0rpx 16rpx;
+}
+.ts {
+  font-size: 24rpx;
+  color: #999;
+  margin: 14rpx 0rpx;
+  padding-right: 29rpx;
+  padding-left: 34rpx;
+}
+.yh {
+  padding-top: 20rpx;
+}
+.yh > .yhtitle {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding-right: 29rpx;
+  padding-left: 34rpx;
+}
+.priceBxs {
+  display: flex;
+  align-items: center;
+}
+.priceBxs > .pricleft {
+  border-radius: 24rpx;
+  border: 1rpx solid #e91313;
+  background-color: rgba(233, 19, 19, 0.1);
+  padding: 0rpx 18rpx;
+  height: 49rpx;
+  line-height: 49rpx;
+  text-align: center;
+  font-size: 30rpx;
+  font-weight: 500;
+  color: #e91313;
+  margin-right: 13rpx;
+}
+.topBox {
+  padding: 32rpx 32rpx 24rpx;
+  border-bottom: 1rpx solid #eeeeee;
+}
+.topBox > .boldFonstType {
+  font-weight: 500;
+  font-size: 30rpx;
+  margin: 16rpx 0rpx 23rpx;
+}
+.topBox > .firstTopL {
+  display: flex;
+  align-items: center;
+}
+.topBox > .firstTopL > .imageBs {
+  width: 331rpx;
+  height: 160rpx;
+  border-radius: 6rpx;
+  overflow: hidden;
+  margin-right: 8rpx;
+  box-shadow: 0rpx 6rpx 6rpx 0rpx rgba(47, 67, 121, 0.08);
+}
+.topBox > .firstTopL > .imageBs > image {
+  width: 100%;
+  height: 100%;
+}
+.topBox > .firstTopL > .textBs {
+  font-size: 30rpx;
+  font-weight: bold;
+  color: #0c141f;
+}
+.content {
+  padding: 24rpx;
+  text-align: left;
+}
+.catalogBox {
+  display: flex;
+  align-items: center;
+  flex-wrap: nowrap;
+  overflow-x: auto;
+  padding-left: 38rpx;
+  max-height: 305rpx;
+  overflow-y: auto;
+  transition: all 0.4s;
+}
+.catalogBox > .catalogA {
+  min-width: 200rpx;
+  height: 48rpx;
+  line-height: 48rpx;
+  // text-align: center;
+  border: 2rpx solid transparent;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  overflow: hidden;
+  word-break: break-all;
+  border-radius: 10rpx;
+  background: rgba(22, 119, 255, 0.05);
+  padding-left: 19rpx;
+  box-sizing: border-box;
+  padding-right: 15rpx;
+  margin-right: 16rpx;
+  margin-bottom: 20rpx;
+  margin-top: 15rpx;
+  font-size: 24rpx;
+  color: #666;
+}
+.catalogBox > .activesq {
+  border-color: #1677ff;
+}
+.changeCatalogBox {
+  display: block;
+}
+.catalogBox::-webkit-scrollbar {
+  display: none; /* Chrome Safari */
+}
+.price_t2 {
+  font-size: 18rpx;
+  font-family: PingFang SC;
+  font-weight: 500;
+  text-decoration: line-through;
+  color: #999999;
+}
+.price_t1 {
+  font-size: 33rpx;
+  font-family: PingFang SC;
+  font-weight: bold;
+  color: #e91313;
+}
+.sc_t {
+  font-size: 22rpx;
+  color: #000000;
+}
+.sc {
+  width: 29rpx;
+  height: 29rpx;
+}
+.buy {
+  width: 138rpx;
+  height: 48rpx;
+  line-height: 48rpx;
+  background: #32467b;
+  border-radius: 10rpx;
+  color: #ffffff;
+  font-size: 28rpx;
+  text-align: center;
+  vertical-align: middle;
+  position: absolute;
+  right: 30rpx;
+}
+.video_body {
+  padding-bottom: 96rpx;
+}
+.footer_tab {
+  position: fixed;
+  bottom: 0;
+  height: 96rpx;
+  width: 100%;
+  background-color: #ffffff;
+}
+.tj_box {
+  width: 50%;
+  display: inline-block;
+  text-align: center;
+  margin: 10rpx 0;
+}
+.teacher_t {
+  font-size: 24rpx;
+  font-family: PingFang SC;
+  font-weight: 400;
+  color: #666666;
+  line-height: 36rpx;
+  margin-left: 15rpx;
+}
+.teacher_img {
+  width: 87rpx;
+  height: 129rpx;
+}
+.t2 {
+  font-size: 24rpx;
+  font-family: PingFang SC;
+  color: #666666;
+  line-height: 36rpx;
+  margin: 15rpx;
+}
+.r_t2 {
+  width: 201rpx;
+  height: 49rpx;
+  background: rgba(22, 119, 255, 0.05);
+  border: 1rpx solid #32467b;
+  border-radius: 16rpx;
+  color: #666666;
+  font-size: 23rpx;
+  text-align: center;
+  display: flex;
+  align-items: center;
+  padding: 5rpx;
+}
+.scroll_box {
+  width: 100%;
+  height: 60rpx;
+  background: #ffffff;
+  box-shadow: 0rpx 0rpx 16rpx 4rpx rgba(145, 156, 178, 0.1);
+  white-space: nowrap;
+  overflow: hidden;
+  margin: 15rpx 0;
+}
+.r_sliper {
+  padding: 0 20rpx;
+}
+.top_line {
+  width: 6rpx;
+  height: 22rpx;
+  background: #32467b;
+  margin-right: 10rpx;
+}
+.video_t2 {
+  font-size: 24rpx;
+  font-family: PingFang SC;
+  font-weight: 500;
+  color: #666666;
+}
+.video_t1 {
+  height: 80rpx;
+  color: #333333;
+  line-height: 80rpx;
+  font-size: 30rpx;
+  font-family: PingFang SC;
+  font-weight: bold;
+  color: #333333;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+
+.notice_wrap {
+  height: 80rpx;
+  display: flex;
+  align-items: center;
+  justify-content: flex-end;
+
+  .video_t1_t {
+    width: 100%;
+    height: 40rpx;
+    line-height: 40rpx;
+    text-align: center;
+    background: rgba(245, 154, 35, 1);
+    color: #333;
+    border-radius: 10rpx;
+    font-size: 24rpx;
+  }
+}
+.video_play {
+  position: absolute;
+  width: 95rpx;
+  height: 95rpx;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  margin: auto;
+}
+.video_box {
+  position: relative;
+
+  .video-toast {
+    position: absolute;
+    width: 686rpx;
+    height: 80rpx;
+    background: rgba(0, 0, 0, 0.6);
+    border-radius: 24rpx;
+    bottom: 100rpx;
+    left: 50%;
+    transform: translateX(-50%);
+    color: #fff;
+    display: flex;
+    font-size: 26rpx;
+    align-items: center;
+    overflow: visible;
+
+    &__text {
+      flex: 1;
+      margin-left: 40rpx;
+    }
+
+    &__btn {
+      width: 180rpx;
+      text-align: center;
+      border-left: 1rpx solid #fff;
+    }
+  }
+
+  .video-toast__close {
+    position: absolute;
+    right: 32rpx;
+    bottom: 184rpx;
+    width: 40rpx;
+    height: 40rpx;
+    line-height: 40rpx;
+    text-align: center;
+    background: rgba(0, 0, 0, 0.6);
+    border-radius: 50%;
+    color: rgba(255, 255, 255, 0.3);
+  }
+}
+.rotoct {
+  transform: rotate(90deg);
+}
+
+.notice_modal {
+  .content {
+    width: 100%;
+    height: 100%;
+    padding: 20rpx;
+
+    .title {
+      color: #333;
+      line-height: 40rpx;
+      font-size: 30rpx;
+      text-align: center;
+      font-weight: bold;
+    }
+    .text {
+      line-height: 40rpx;
+    }
+  }
+}
+
+
+</style>

+ 112 - 3
pages3/polyv/detail.vue

@@ -37,6 +37,9 @@
             @fullscreenchange="fullscreenchange"
             @error="playError"
             :autoplay="true"
+						:page-gesture="true"
+						:vslide-gesture="true"
+						:vslide-gesture-in-fullscreen="true"
             :isAllowSeek="isAllowSeek"
             :playbackRate="playbackRate"
             :startTime="startTime"
@@ -66,6 +69,9 @@
           <player
             class="plv-mp-demo-player"
             :videoOption="videoOption"
+						:page-gesture="true"
+						:vslide-gesture="true"
+						:vslide-gesture-in-fullscreen="true"
             @onLiveStatusChange="playerLiveStatusChange"
           />
         </view>
@@ -103,6 +109,11 @@
       <scroll-view class="box_in" scroll-y="true">
         <!--目录 -->
         <view v-show="current == 0">
+					<view class="top__header" v-if="livingItem" @click="goLive(livingItem)">
+						<image class="img" src="/pages5/static/live.png" mode="widthFix"></image>
+						<view class="note">正在直播中</view>
+						<view class="title">{{livingItem.name}}</view>
+					</view>
           <view class="menuBox" v-for="(item, index) in menuList" :key="index">
             <!--模块 -->
             <view v-if="item.type == 1"
@@ -504,6 +515,7 @@ import plv from "../static/polyv-sdk/index";
 import courseModule from "@/components/course/courseModule.vue";
 import courseChapter from "@/components/course/courseChapter.vue";
 import courseSection from "@/components/course/courseSection.vue";
+import {WEBVIEW_URL} from '@/common/request.js'
 // import { websocket } from "@/common/socket.js";
 import { mapGetters, mapMutations } from "vuex";
 export default {
@@ -601,6 +613,7 @@ export default {
       isRebuild: false, //视频是否从重修目录点击
 			isFocus:false,
 			clearTimer:null,
+			livingItem:'',
     };
   },
   computed: {
@@ -613,6 +626,7 @@ export default {
     this.courseDetail();
     this.getGoodsDetail();
     this.getAnswerList();
+		this.studyRecordMenuAllList();
     this.answerTimer = setInterval(() => {
       this.getAnswerList();
     }, 5000);
@@ -634,7 +648,9 @@ export default {
       console.log("this.playNoteVideo");
 			
 			this.playNoteVideo(item)
-    }
+    } else {
+			this.studyRecordQueryLiveLast();
+		}
   },
   onShow() {
     var self = this;
@@ -733,7 +749,43 @@ export default {
     this.updateChapterOpen(true);
   },
   methods: {
-    ...mapMutations(["updateChapterOpen"]),
+    ...mapMutations(["updateChapterOpen","updateLiveLast"]),
+		/**
+		 * 获取上次观看的直播
+		 */
+		studyRecordGetLastLive() {
+			this.$api.studyRecordGetLastLive({
+				orderGoodsId:this.orderGoodsId,
+				courseId:this.courseId
+			}).then(res => {
+				console.log(res,'liveres')
+				this.updateLiveLast(res.data.data)
+			})
+		},
+		studyRecordQueryLiveLast() {
+			this.$api.studyRecordQueryLiveLast({
+				orderGoodsId:this.orderGoodsId,
+				courseId:this.courseId
+			}).then(res => {
+				console.log(res,'couse')
+				if(res.data.data) {
+					if(res.data.data.sectionType == 1) { //录播
+					this.$store.commit("setPlaySectionId", { playSectionId: res.data.data.sectionId });
+					this.$store.commit("setPlayVID", { playVID: res.data.data.recordingUrl });
+					this.sectionItem = res.data.data;
+						this.playVideo(res.data.data)
+					} else if(res.data.data.sectionType == 2) { //直播
+						this.studyRecordGetLastLive();
+					} else if(res.data.data.sectionType == 3) { //回放
+					this.$store.commit("setPlaySectionId", { playSectionId: res.data.data.sectionId });
+					this.$store.commit("setPlayVID", { playVID: res.data.data.recordingUrl });
+						this.sectionItem = res.data.data;
+						this.playVideo(res.data.data)
+					}
+					
+				}
+			})
+		},
     /**
      * 模块大节播放完毕,刷新列表
      */
@@ -920,6 +972,26 @@ export default {
           });
       }
     },
+		goLive(item) {
+			let moduleId = item.moduleId || 0;
+			let chapterId = item.chapterId || 0;
+			let sectionId = item.sectionId || item.menuId;
+			let encode = encodeURIComponent(WEBVIEW_URL+'pages/live/index?token='+uni.getStorageSync('token')+'&userInfo='+JSON.stringify(this.userInfo)+'&channelId='+item.liveUrl+'&gradeId='+this.gradeId+'&courseId='+this.courseId+'&goodsId='+this.goodsId+'&orderGoodsId='+this.orderGoodsId+'&sectionId='+sectionId+'&chapterId='+chapterId+'&moduleId='+moduleId)
+			uni.navigateTo({
+				url:`../../pages/webview/index?url=`+encode
+			})
+		},
+		studyRecordMenuAllList() {
+			this.$api.studyRecordMenuAllList({
+				courseId:this.courseId,
+				gradeId:this.gradeId,
+				goodsId:this.goodsId
+			}).then(res => {
+				let nowTime = Number(new  Date().getTime()/1000).toFixed(0)
+				// this.livingItem = res.data.data[0]
+				this.livingItem = res.data.data.find(item => item.liveStartTime<=nowTime&&item.liveEndTime>nowTime);
+			})
+		},
 		getbaseprofiletplists() {
 			let self = this;
 			this.getCameraSetting();
@@ -1435,7 +1507,7 @@ export default {
     },
     //正常播放视频
     async playVideo(item) {
-      console.log(item);
+      console.log(item,'222');
       if (this.timer) {
         clearInterval(this.timer);
       }
@@ -2265,6 +2337,43 @@ export default {
 </script>
 
 <style lang="scss" scope>
+	.top {
+		&__header {
+			position:relative;
+			width:100%;
+			height:150rpx;
+			padding:24rpx 150rpx 24rpx 24rpx;
+			
+			.img {
+				position:absolute;
+				left:0;
+				top:0;
+				width:100%;
+			}
+			
+			.note {
+				position:relative;
+				z-index: 10;
+				font-size: 24rpx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #EFDBFF;
+			}
+			
+			.title {
+				position:relative;
+				z-index: 10;
+				font-size: 26rpx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #FFFFFF;
+			}
+			
+			.desc {
+				
+			}
+		}
+	}
 .polyv_detail {
   display: flex;
   flex-direction: column;

+ 18 - 2
pages5/exam/index.vue

@@ -8,11 +8,11 @@
 			</view>
 			<view class="examItem" @click="goList(0)">
 				<view class="item">未考试</view>
-				<view class="item"><text class="num">{{yyNum}}</text>个<u-icon name="arrow-right" color="#999999" size="28"></u-icon></view>
+				<view class="item"><text class="num">{{total1}}</text>个<u-icon name="arrow-right" color="#999999" size="28"></u-icon></view>
 			</view>
 			<view class="examItem" @click="goList(1)">
 				<view class="item">已结束</view>
-				<view class="item"><text class="num">{{yyNum}}</text>个<u-icon name="arrow-right" color="#999999" size="28"></u-icon></view>
+				<view class="item"><text class="num">{{total2}}</text>个<u-icon name="arrow-right" color="#999999" size="28"></u-icon></view>
 			</view>
 			<view class="examItem" @click="goResult">
 				<view class="item">
@@ -33,14 +33,30 @@ export default {
 	data() {
 		return {
 			yyNum:0,
+			total1:0,
+			total2:0
 		};
 	},
 	onLoad(){
+		this.getCount()
 	},
 	onShow() {
 		// this.getInfo()
 	},
 	methods: {
+		getCount() {
+			this.$api.mockSubscribeListSubscribe({
+				mockStatus:0,
+			}).then(res => {
+				this.total1 = res.data.total
+			})
+			
+			this.$api.mockSubscribeListSubscribe({
+				mockStatus:1,
+			}).then(res => {
+				this.total2 = res.data.total
+			})
+		},
 		getInfo(){
 			this.$api.getinfoAttached().then(res => {
 				if (res.data.code === 200) {

+ 199 - 79
pages5/examAppointList/index.vue

@@ -3,17 +3,17 @@
 		<nav-bar title="模考预约" class="nav"></nav-bar>
 		<view class="tabs">
 			<view class="tab" :class="{ active: index == 1 }" data-index="1" @click="tab(1)">
-				<view>全部</view>
+				<view>{{ businessName}}</view>
 				<u-icon class="icon" :class="index ==1? 'animals':''" name="arrow-down"></u-icon>
 			</view>
 			<view class="tab" :class="{ active: index == 2 }" data-index="2">
 				<view class="dateRange">
-					<picker mode="date" :value="dateFrom" :start="startDate" :end="endDate" @change="bindDateFromChange">
-						<view class="uni-input">{{dateFrom}}</view>
+					<picker mode="date" :value="param.startTime" :end="endDate" @change="bindDateFromChange">
+						<view class="uni-input">{{param.startTime || '开始时间'}}</view>
 					</picker>
 					- 
-					<picker mode="date" :value="dateTo" :start="startDate" :end="endDate" @change="bindDateToChange">
-						<view class="uni-input">{{dateTo}}</view>
+					<picker mode="date" :value="param.endTime" :end="endDate" @change="bindDateToChange">
+						<view class="uni-input">{{param.endTime || '结束时间'}}</view>
 					</picker></view>
 				<u-icon class="icon" name="calendar"></u-icon>
 			</view>
@@ -21,15 +21,7 @@
 		<view class="scroll">
 			<scroll-view scroll-x="true" class="scroll-x" >
 				<view class="content">
-					<view class="scroll-tag active">AAAAAAAAAAAAAA</view>
-					<view class="scroll-tag">bbbbbbbbbbbb</view>
-					<view class="scroll-tag">ccccccccccc</view>
-					<view class="scroll-tag">AAAAAAAAAAAAAA</view>
-					<view class="scroll-tag">bbbbbbbbbbbb</view>
-					<view class="scroll-tag">ccccccccccc</view>
-					<view class="scroll-tag">AAAAAAAAAAAAAA</view>
-					<view class="scroll-tag">bbbbbbbbbbbb</view>
-					<view class="scroll-tag">ccccccccccc</view>
+					<view v-for="(item,index) in sList" :key="index" class="scroll-tag" :class="{active:param.subjectId == item.id}" @click="tagSelect(item)">{{item.subjectName}}</view>
 				</view>
 				
 			</scroll-view>
@@ -37,15 +29,17 @@
 		
 
 		<view class="record">
-			<view class="item" v-for="(item,index) in 5" :key="index">
-				<view class="item__header">建设工程法规及相关知识建设工程</view>
+			<view class="item" v-for="(item,index) in mockList" :key="index">
+				<view class="item__header">{{item.applyName}}</view>
 				<view class="item__body">
 					<view class="title">
 						<image class="img" mode="widthFix" src="/pages5/static/time.png"></image>
 						<text>考试时间</text>
 					</view>
-					<view class="desc">2022年4月15日(周五) 9:00-11:00 </view>
-					<view class="btn" @click="appoint(item)" :class="{active: index % 2 == 0}">预约考试</view>
+					<view class="desc">{{$method.timestampToTime(item.examTime)}}
+						<view> {{item.startTime}} - {{item.endTime}} </view>
+					</view>
+					<view class="btn" @click="appoint(item)" :class="{disabled: !canApply(item) || !item.isSubscribe }">{{item.isSubscribe?'预约考试' : '已预约'}}</view>
 				</view>
 			</view>
 		</view>
@@ -59,10 +53,9 @@
 		<view class="modal" :style="{top:modalTop+'px'}" v-if="index == 1">
 			<view class="content">
 				<scroll-view scroll-y="true" style="height:100%">
-					<view class="top" :class="activeIndex === 0 ? 'activesty' : ''" @click="testClick(3)">全部</view>
 					<view class="list">
-						<view class="item" :class="activeIndex == listItem.goodsId ? 'activesty' : ''" v-for="(listItem,listIndex) in list" :key="listIndex" @click="testClick(listItem)">
-							{{ listItem.goodsName }}
+						<view class="item" :class="param.businessId == listItem.businessId ? 'activesty' : ''" v-for="(listItem,listIndex) in businesslist" :key="listIndex" @click="testClick(listItem)">
+							{{ listItem.businessName }} {{listItem.projectName}}
 						</view>
 					</view>
 				</scroll-view>
@@ -71,17 +64,6 @@
 			<view class="modal_wrap" @click="index = 0"></view>
 		</view>
 		
-		<view class="notice_modal" :style="{top:modalTop+'px'}" v-if="index == 2">
-			<view class="content">
-				<scroll-view scroll-y="true" style="height:100%">
-					<view class="top" :class="typeIndex === 0 ? 'activesty' : ''" @click="paperClick(3)">全部试卷类型</view>
-					<view class="list">
-						<view class="item" :class="typeIndex == listItem.paperId ? 'activesty' : ''" v-for="(listItem,listIndex) in list1" :key="listIndex" @click="paperClick(listItem)">{{ listItem.paperName }}</view>
-					</view>
-				</scroll-view>
-			</view>
-			<view class="modal_wrap" @click="index = 0"></view>
-		</view>
 		
 		<u-popup class="notice__modal" v-model="noticeModal" mode="center" border-radius="24" :mask-close-able="false">
 			<view class="notice__content">
@@ -114,23 +96,26 @@
 							</view>
 							<view>
 								<text class="bold text">模考场次: </text>
-								<text class="text">2022年考前一建模拟考试</text>
+								<text class="text">{{showItem.applyName}}</text>
 							</view>
 							<view>
 								<text class="bold text">项目:   </text>
-								<text class="text">一级建造师</text>
+								<text class="text">{{ showItem.businessName }} {{ showItem.projectName }}</text>
 							</view>
 							<view>
 								<text class="bold text">专业:</text>
-								<text class="text">市政专业</text>
+								<text class="text">{{showItem.categoryName}}</text>
 							</view>
 							<view>
 								<text class="bold text">科目:</text>
-								<text class="text">建设工程经济</text>
+								<text class="text">{{showItem.subjectName}}</text>
 							</view>
 							<view>
 								<text class="bold text">考试时间:</text>
-								<text class="text">2022年4月15日(周五)  9:00-10:00</text>
+								<text class="text">
+									{{ $method.timestampToTime(showItem.examTime) }}
+									{{ showItem.startTime }} - {{ showItem.endTime }}
+								</text>
 							</view>
 							<view>请准时参加考试哦~</view>
 							
@@ -155,7 +140,7 @@
 						</view>
 				</view>
 				<view class="footer">
-					<view class="btn close" @click="openAppoint = false">我知道了</view>
+					<view class="btn close" @click="closeNotice()">我知道了</view>
 				</view>
 			</view>
 		</u-popup>
@@ -163,37 +148,49 @@
 </template>
 
 <script>
+	import {mapGetters} from 'vuex'
 export default {
+	computed:{
+		...mapGetters(['userInfo'])
+	},
 	data() {
 		return {
+			tagActive:'',
 			openAppoint:false,
 			appointModal:false,
 			noticeModal:false,
 			index: 0,
 			list: [],
 			list1: [],
-			recordList: [],
-			goodsData: {},
+			mockList: [],
+			businesslist:[],
 			param: {
+				endTime:'',
+				startTime:'',
 				pageNum: 1,
-				pageSize: 10
+				pageSize: 10,
+				businessId:'',
+				subjectId:''
 			},
-			dateFrom:'',
-			dateTo:'',
 			isRepeat:false,
 			total: 0,
-			activeIndex: 0,
+			activeIndex: '',
 			typeIndex:0,
 			itemIndex:'',
 			modalTop:0,
 			endDate:'',
+			businessName:'',
+			nowTime:'',
+			sList:[],
+			showItem:{},
 		};
 	},
-	onLoad(option) {
-		this.dateFrom = this.$method.timestampToTime(new Date().getTime() / 1000).replace(/-/g,'/');
-		this.dateTo = this.$method.timestampToTime(new Date().getTime() / 1000).replace(/-/g,'/');
+	async onLoad(option) {
 		this.endDate = this.$method.timestampToTime(new Date().getTime() / 1000).replace(/-/g,'/');
+		this.nowTime = +this.$method.timest();
+		await this.mockApplyListApplyBusiness();
 		
+		this.mockApplyListApply();
 		uni.getSystemInfo({
 			success:(e) => {
 				let info = uni.createSelectorQuery().select(".nav");
@@ -202,8 +199,6 @@ export default {
 					let info = uni.createSelectorQuery().select(".tabs");
 					info.boundingClientRect((tabData) => { //data - 各种参数
 						this.modalTop = navData.height + tabData.height
-						console.log(navData) // 获取元素宽度
-						console.log(tabData) // 获取元素宽度
 					}).exec()
 				}).exec()
 			}
@@ -211,44 +206,153 @@ export default {
 	},
 	onPullDownRefresh() {
 		let that = this;
-		this.param = {
-			pageNum: 1,
-			pageSize: 10
-		};
-		this.getExamRecordList();
+		this.param.pageNum = 1;
+		this.mockApplyListApply();
 		setTimeout(function() {
 			uni.stopPullDownRefresh();
 		}, 500);
 	},
 	onReachBottom() {
-		if (this.recordList.length < this.total) {
+		if (this.mockList.length < this.total) {
 			this.param.pageNum++;
-			this.getExamRecordList();
+			this.mockApplyListApply();
 		}
 	},
 	onShow() {
-		if(this.isRepeat) {
-			this.addRecord();
-		} else {
-			if(this.itemIndex !== '') {
-				this.refreshByIndex();
-			}
-		}
 		
 	},
 	methods: {
+		closeNotice() {
+			this.openAppoint = false;
+			this.param.pageNum = 1;
+			this.mockList = [];
+			this.mockApplyListApply()
+		},
+		canApply(item) {
+			console.log(item)
+			let startTime = item.applyStartTime
+			let endTime = item.applyEndTime
+			
+			if(this.nowTime >= startTime && this.nowTime <= endTime) {
+				return true;
+			} else {
+				return false;
+			}
+		},
+		tagSelect(item) {
+			this.param.subjectId = item.id;
+			this.mockList = []
+			this.mockApplyListApply()
+		},
+		testClick(item) {
+			if(!item) {
+				this.param.businessId = ''
+				this.businessId = ''
+				this.index = 0;
+				this.mockList = []
+				this.mockApplyListApply();
+				return;
+			}
+			console.log(item,'item')
+			this.param.businessId = item.businessId
+			this.businessName = item.businessName + item.projectName
+			this.index = 0;
+			this.mockList = []
+			this.mockApplyListApply();
+			
+			console.log(this.b)
+		},
+		mockApplyListApplyBusiness() {
+			return new Promise(resolve => {
+				this.$api.mockApplyListApplyBusiness().then(async res => {
+					this.businesslist = res.data.rows;
+					this.param.businessId = res.data.rows[0].businessId;
+					this.businessName = res.data.rows[0].businessName + res.data.rows[0].projectName
+					await this.subjectList({businessId:res.data.rows[0].businessId,projectId:res.data.rows[0].projectId})
+					resolve()
+				})
+			})
+			
+		},
+		mockApplyListApply() {
+			let param = JSON.parse(JSON.stringify(this.param))
+			if(param.endTime) {
+				param.endTime = this.$method.TimeTotimestamp(param.endTime)
+			}
+			
+			if(param.startTime) {
+				param.startTime = this.$method.TimeTotimestamp(param.startTime)
+			}
+			
+			
+			this.$api.mockApplyListApply(param).then(res => {
+				this.mockList.push(...res.data.rows)
+				this.total = res.data.total;
+			})
+		},
 		refreshByIndex() {
-			this.$api.examRecordGroupList({
-				pageNum: this.itemIndex+1,
-				pageSize: 1
-			}).then(res => {
-				this.$set(this.recordList,this.itemIndex,res.data.rows[0])
-				this.itemIndex = ''
-			});
+			
+		},
+		subjectList(data) {
+			return new Promise(resolve => {
+				
+				let self = this;
+				this.$api.subjectList(data).then(res => {
+					if(res.data.code==200){
+						self.sList = res.data.rows
+						let allItem = {id:'',subjectName:'全部'}
+						self.sList.unshift(allItem)
+						this.param.subjectId = '';
+						
+						resolve()
+					}
+				});
+			})
 		},
 		
 		appoint(item) {
-			this.appointModal = true;
+			let canApply = this.canApply(item);
+			if(!canApply) {
+				uni.showToast({
+					icon:'none',
+					title:'不在预约时间范围'
+				})
+				
+				return;
+			} 
+			
+			if(!item.isSubscribe) {
+				uni.showToast({
+					icon:'none',
+					title:'您已预约'
+				})
+				return;
+			}
+			
+			this.$api.mockSubscribe({
+				applySiteExamTime:item.examTime,
+				applySiteEndTime:item.endTime,
+				applySiteStartTime:item.startTime,
+				applyId:item.applyId,
+				mockMajorSubjectId:item.mockMajorSubjectId,
+				eachExamId:item.eachExamId
+				// applySiteExamTime:1653899220,
+				// applySiteEndTime:"17:27:54",
+				// applySiteStartTime:'16:27:54', 
+				// applyId:26,
+				// mockMajorSubjectId:49
+			}).then(res => {
+				console.log(res)
+				this.showItem = item;
+				this.appointModal = true;
+				
+			}).catch(err => {
+				uni.showToast({
+					icon:'none',
+					title:err.msg
+				})
+			})
+			
 		},
 		tab(index) {
 			console.log(index,this.index)
@@ -260,11 +364,17 @@ export default {
 			console.log(this.index);
 		},
 		bindDateFromChange(e) {
-			this.dateFrom = e.detail.value
+			this.param.startTime = e.detail.value
+			this.param.pageNum = 1;
+			this.mockList = []
+			this.mockApplyListApply();
 		},
 		
 		bindDateToChange(e) {
-			this.dateTo = e.detail.value
+			this.param.endTime = e.detail.value
+			this.param.pageNum = 1;
+			this.mockList = []
+			this.mockApplyListApply();
 		}
 	}
 };
@@ -284,6 +394,7 @@ page {
 	left: 0;
 	width: 100%;
 	display: flex;
+	height:80rpx;
 	z-index: 10;
 	.tab {
 		padding:0 18rpx;
@@ -300,6 +411,12 @@ page {
 			border-right:1px solid #EEEEEE;
 		}
 		
+		.uni-input {
+			text-align: center;
+			width:150rpx;
+		}
+		
+		
 		.dateRange {
 			display: flex;
 			justify-content: space-between;
@@ -320,10 +437,11 @@ page {
 	.scroll-x {
 		
 		.content {
-				display: flex;
 				padding:16rpx;
+				white-space:nowrap;
 				
 				.scroll-tag {
+					display: inline-block;
 					padding:11rpx 17rpx;
 					background: #fff;
 					color:#666666;
@@ -404,13 +522,14 @@ page {
 				line-height: 62rpx;
 				text-align: center;
 				font-size: 28rpx;
-					border: 1px solid #D9D9D9;
-					color:#D9D9D9;
 				
-				&.active {
+				border: 1px solid #007AFF;
+				color:#007AFF;
 					
-					border: 1px solid #007AFF;
-					color:#007AFF;
+				
+				&.disabled {
+					border: 1px solid #D9D9D9;
+					color:#D9D9D9;
 				}
 			}
 		}
@@ -619,6 +738,7 @@ page {
 	position:fixed;
 	left:0;
 	top:0;
+	z-index: 9999;
 	width:100%;
 	height:100%;
 	background:rgba(0,0,0,0.3);

+ 52 - 232
pages5/examBank/index.vue

@@ -717,17 +717,7 @@
           <view class="footer_btn">
             <view
               class="collect"
-              :class="{ show: goodsId && !isFromVideo ? true : false }"
-              @click="collect(collectList[bankIndex], bankIndex)"
             >
-              <view v-if="collectList[bankIndex]">
-                <image src="/static/icon/collected.png" mode=""></image>
-                <view>取消收藏</view>
-              </view>
-              <view v-if="!collectList[bankIndex]">
-                <image src="/static/icon/collect.png" mode=""></image>
-                <view>收藏</view>
-              </view>
             </view>
             <view class="flex_center" @click="openFooterTab">
               <view class="up-icon">
@@ -866,7 +856,7 @@ export default {
   data() {
     return {
       showpopups: false,
-      id: "",
+      examId: "",
       current: 0,
       questionList: [],
       ast: ["A", "B", "C", "D", "E", "F", "G"],
@@ -877,37 +867,28 @@ export default {
       showDialog: false,
       bankList: [],
       collectList: [],
-      goodsId: "",
       recordId: "",
       isSubmit: false,
       lastTime: 0, //剩余考试时长
       allTimes: 0, //总考试时长
       timer: null,
       wrongList: [],
-      bankType: 0, //试卷类型
+      bankType: 2, //试卷类型
       needBack: false, //是否是考试
       testOver: false,
       isLastCount: false, //是否有未答题目
       lastCount: 0, //剩余没有回答的题目数
-      chapterId: 0,
-      moduleId: 0,
       showArrow: false, //退出提示
-      isFromVideo: "",
       gradeId: "",
       examData: {},
-      orderGoodsId: "",
+			eachExamId:0,
       cgType: 0, //对应设计稿弹窗编码
     };
   },
   async onLoad(option) {
-    this.orderGoodsId = option.orderGoodsId || 0;
     this.current = +option.current || 0;
-    this.id = option.id;
-    this.goodsId = option.goodsid;
-    this.chapterId = option.chapterId || 0;
-    this.moduleId = option.moduleId || 0;
-    this.isFromVideo = option.isFromVideo || "";
-    this.gradeId = option.gradeId || "";
+		this.eachExamId = option.eachExamId
+    this.examId = option.examId;
     let isBack = option.isback;
 
     let showDialog = uni.getStorageSync("showDialog");
@@ -946,7 +927,7 @@ export default {
       }, 1000);
     } else {
       //进入页面
-      await this.bankExam();
+      // await this.bankExam();
       this.goodsQuestionList();
     }
   },
@@ -962,18 +943,17 @@ export default {
       clearInterval(this.timer);
       uni.navigateTo({
         url:
-          "/pages2/bank/questionBank?id=" +
-          this.id +
-          "&goodsid=" +
-          this.goodsId +
-          "&isback=true&orderGoodsId=" +
-          this.orderGoodsId,
+          "/pages2/bank/questionBank?examId=" +
+          this.examId +
+          "&eachExamId=" +
+          this.eachExamId +
+          "&isback=true"
       });
     } else {
       //点击返回按钮确认允许退出,记录答题记录
       clearInterval(this.timer);
 
-      this.examRecordEdit();
+      this.mockRecordEdit();
     }
   },
   methods: {
@@ -988,7 +968,7 @@ export default {
      */
     bankExam() {
       return new Promise((resolve) => {
-        this.$api.bankExam(this.id).then((res) => {
+        this.$api.bankExam(this.examId).then((res) => {
           this.bankType = res.data.data.doType;
           this.examData = res.data.data;
           if (this.bankType == 2) {
@@ -1272,17 +1252,14 @@ export default {
 
       //交卷
       this.$api
-        .examRecordEdit({
-          examId: this.id,
-          goodsId: this.goodsId,
-          orderGoodsId: this.orderGoodsId,
+        .mockRecordEdit({
+          examId: this.examId,
           reportStatus: reportStatus,
           recordId: this.recordId,
           rightQuestionNum: number,
+					eachExamId:this.eachExamId,
           status: 1,
 					lessQuestionNum:lessQuestionNum,
-          moduleExamId: this.moduleId || 0,
-          chapterExamId: this.chapterId || 0,
           doQuestionIds: doQuestionIds.join(","),
           rightQuestionIds: rightQuestionIds.join(","),
           doQuestionNum: doQuestionNum,
@@ -1297,19 +1274,16 @@ export default {
           if (res.data.code == 200) {
           }
         });
+				
+				//错题集id提交(客观题)
+				this.$api
+				  .mockWrongRecord({
+				    examId: this.examId,
+				    questionIds: doWrongQuestionIds,
+				    recordId: this.recordId,
+				  })
+				  .then((res) => {});
 
-      //错题集id提交(客观题)
-      this.$api
-        .examWrongRecord({
-          orderGoodsId: this.orderGoodsId,
-          moduleExamId: this.moduleId || 0,
-          chapterExamId: this.chapterId || 0,
-          examId: this.id,
-          goodsId: this.goodsId,
-          questionIds: doWrongQuestionIds,
-          recordId: this.recordId,
-        })
-        .then((res) => {});
     },
     /**
      * 立即交卷
@@ -1322,7 +1296,7 @@ export default {
     /**
      * 离开页面统计回答正确题数
      */
-    examRecordEdit() {
+    mockRecordEdit() {
       if (!this.isSubmit) {
         let number = 0;
         let score = 0;
@@ -1419,15 +1393,13 @@ export default {
         });
 
         this.$api
-          .examRecordEdit({
-            orderGoodsId: this.orderGoodsId,
-            examId: this.id,
+          .mockRecordEdit({
+            examId: this.examId,
+						eachExamId:this.eachExamId,
             goodsId: this.goodsId,
             recordId: this.recordId,
             doQuestionIds: doQuestionIds.join(","),
             rightQuestionNum: number,
-            moduleExamId: this.moduleId || 0,
-            chapterExamId: this.chapterId || 0,
             status: 0,
             doQuestionNum: doQuestionNum,
             historyExamJson: JSON.stringify(this.questionList),
@@ -1439,7 +1411,7 @@ export default {
      * 记录总题数
      * hasSpecial (是否包含简答和案例) true 包含  false 不包含
      */
-    examRecord(hasSpecial) {
+    mockRecord(hasSpecial) {
       let questionList = 0;
       // if(!hasSpecial) {
       this.questionList.forEach((item, index) => {
@@ -1452,21 +1424,15 @@ export default {
       // }
 
       this.$api
-        .examRecord({
-          chapterExamId: this.chapterId || 0,
-          orderGoodsId: this.orderGoodsId,
-          moduleExamId: this.moduleId || 0,
-          examId: this.id,
-          goodsId: this.goodsId,
+        .mockRecord({
+          examId: this.examId,
+					eachExamId:this.eachExamId,
           totalQuestionNum: questionList,
           allQuestionNum: this.questionList.length,
         })
         .then((res) => {
           this.recordId = res.data.data;
           //获取recordId 初始化先提交题目 以防突然下次继续做题退出报错
-          if (this.bankType == 1) {
-            this.examRecordEdit();
-          }
         });
     },
     /**
@@ -1497,7 +1463,7 @@ export default {
     goodsQuestionList() {
       this.$api
         .goodsQuestionList({
-          examId: this.id,
+          examId: this.examId,
         })
         .then((res) => {
           if (!res.data.data.length) {
@@ -1665,8 +1631,7 @@ export default {
           this.questionList = res.data.data;
 
           this.lastCount = this.questionList.length;
-          this.examRecord();
-          this.getCollectInfo(this.current);
+          this.mockRecord();
         });
     },
     /**
@@ -1676,31 +1641,6 @@ export default {
       if (this.questionList[bindex].ques) return;
       this.$set(this.questionList[bindex], "ques", optionsId);
       this.isDoOver();
-
-      // 回答错误
-      if (this.questionList[bindex].ques != this.questionList[bindex].ans) {
-        this.$api
-          .examWrongRecord({
-            orderGoodsId: this.orderGoodsId,
-            examId: this.id,
-            goodsId: this.goodsId,
-            moduleExamId: this.moduleId || 0,
-            chapterExamId: this.chapterId || 0,
-            questionIds: [this.questionList[bindex].questionId],
-            recordId: this.recordId,
-          })
-          .then((res) => {});
-      } else {
-        // let question = this.wrongList.find(item => item.questionId == this.questionList[bindex].questionId);
-        // if(question) {
-        // 	this.$api.wrongRecordDelete({
-        // 		"examId": +this.id,
-        // 		"goodsId": +this.goodsId,
-        // 		"questionId": this.questionList[bindex].questionId,
-        // 	}).then(res => {
-        // 	})
-        // }
-      }
     },
 
     /**
@@ -1774,30 +1714,6 @@ export default {
           );
         }
       );
-      // 回答错误
-      if (isWrong) {
-        this.$api
-          .examWrongRecord({
-            orderGoodsId: this.orderGoodsId,
-            examId: this.id,
-            goodsId: this.goodsId,
-            moduleExamId: this.moduleId || 0,
-            chapterExamId: this.chapterId || 0,
-            questionIds: [this.questionList[bindex].questionId],
-            recordId: this.recordId,
-          })
-          .then((res) => {});
-      } else {
-        // let question = this.wrongList.find(item => item.questionId == this.questionList[bindex].questionId);
-        // if(question) {
-        // 	this.$api.wrongRecordDelete({
-        // 		"examId": +this.id,
-        // 		"goodsId": +this.goodsId,
-        // 		"questionId": this.questionList[bindex].questionId,
-        // 	}).then(res => {
-        // 	})
-        // }
-      }
     },
 
     /**
@@ -1835,30 +1751,6 @@ export default {
       if (this.questionList[bindex].ques) return;
       this.$set(this.questionList[bindex], "ques", index + "");
       this.isDoOver();
-      // 回答错误
-      if (this.questionList[bindex].ques != this.questionList[bindex].ans) {
-        this.$api
-          .examWrongRecord({
-            orderGoodsId: this.orderGoodsId,
-            examId: this.id,
-            goodsId: this.goodsId,
-            moduleExamId: this.moduleId || 0,
-            chapterExamId: this.chapterId || 0,
-            questionIds: [this.questionList[bindex].questionId],
-            recordId: this.recordId,
-          })
-          .then((res) => {});
-      } else {
-        // let question = this.wrongList.find(item => item.questionId == this.questionList[bindex].questionId);
-        // if(question) {
-        // 	this.$api.wrongRecordDelete({
-        // 		"examId": +this.id,
-        // 		"goodsId": +this.goodsId,
-        // 		"questionId": this.questionList[bindex].questionId,
-        // 	}).then(res => {
-        // 	})
-        // }
-      }
     },
 
     /**
@@ -1882,29 +1774,9 @@ export default {
 
     swiperChange(e) {
       this.current = e.detail.current;
-      this.getCollectInfo(this.current);
     },
 
-    /**
-     * @param {Object} current
-     * 获取收藏信息
-     */
-    getCollectInfo(current) {
-      this.$api
-        .getCollectInfo({
-          examId: this.id,
-          questionId: this.questionList[current].questionId,
-          goodsId: this.goodsId,
-          orderGoodsId: this.orderGoodsId,
-        })
-        .then((res) => {
-          if (res.data.code == 500) {
-            this.$set(this.collectList, current, false);
-          } else if (res.data.code == 200) {
-            this.$set(this.collectList, current, res.data.data);
-          }
-        });
-    },
+    
     pdsubmit() {
       // if (this.bankType == 1) {
       let ansCount = this.questionOverNum(true); //已答题数
@@ -2083,17 +1955,14 @@ export default {
 
       //交卷
       this.$api
-        .examRecordEdit({
-          examId: this.id,
-          goodsId: this.goodsId,
+        .mockRecordEdit({
+          examId: this.examId,
+					eachExamId:this.eachExamId,
           reportStatus: reportStatus,
           recordId: this.recordId,
           rightQuestionNum: number,
-          orderGoodsId: this.orderGoodsId,
           status: 1,
 					lessQuestionNum:lessQuestionNum,
-          moduleExamId: this.moduleId || 0,
-          chapterExamId: this.chapterId || 0,
           doQuestionIds: doQuestionIds.join(","),
           rightQuestionIds: rightQuestionIds.join(","),
           doQuestionNum: doQuestionNum,
@@ -2115,76 +1984,27 @@ export default {
             setTimeout(() => {
               uni.redirectTo({
                 url:
-                  "/pages2/bank/question_report?goodsId=" +
-                  this.goodsId +
-                  "&chapterId=" +
-                  this.chapterId +
-                  "&moduleId=" +
-                  this.moduleId +
-                  "&examId=" +
-                  this.id +
+                  "/pages5/examReport/index?&examId=" +
+                  this.examId +
                   "&id=" +
-                  this.recordId +
-                  "&orderGoodsId=" +
-                  this.orderGoodsId,
+                  this.recordId+
+									"&eachExamId"+this.eachExamId
               });
             }, 1000);
           }
         });
+				
+				//错题集id提交(客观题)
+				this.$api
+				  .mockWrongRecord({
+				    examId: this.examId,
+				    questionIds: doWrongQuestionIds,
+				    recordId: this.recordId,
+				  })
+				  .then((res) => {});
 
-      //错题集id提交(客观题)
-      this.$api
-        .examWrongRecord({
-          examId: this.id,
-          goodsId: this.goodsId,
-          orderGoodsId: this.orderGoodsId,
-          questionIds: doWrongQuestionIds,
-          recordId: this.recordId,
-        })
-        .then((res) => {});
     },
 
-    /**
-     * @param {Object} state
-     * @param {Object} index
-     * 收藏
-     */
-    collect(state, index) {
-      if (!state) {
-        this.$api
-          .collectQuestion({
-            examId: this.id,
-            questionId: this.questionList[index].questionId,
-            goodsId: this.goodsId || "",
-            orderGoodsId: this.orderGoodsId,
-          })
-          .then((res) => {
-            if (res.data.code == 200) {
-              this.$set(this.collectList, index, true);
-              uni.showToast({
-                title: "收藏成功",
-                duration: 2000,
-                icon: "none",
-              });
-              this.getCollectInfo(index);
-            }
-          });
-      } else {
-        this.$api
-          .deleteCollectQuestion(this.collectList[index].collectQuestionId)
-          .then((res) => {
-            if (res.data.code == 200) {
-              this.$set(this.collectList, index, false);
-              uni.showToast({
-                title: "取消收藏成功",
-                duration: 2000,
-                icon: "none",
-              });
-            }
-          });
-      }
-      return;
-    },
 
     /**
      * @param {Object} imgIndex

+ 50 - 6
pages5/examCount/index.vue

@@ -5,10 +5,10 @@
 			<view class="title">距离管理开考还有</view>
 			<view class="circle">
 				<image class="img" mode="widthFix" src="../static/time-circle.png"></image>
-				<view class="time">08:56</view>
+				<view class="time">{{timeText}}</view>
 			</view>
 			
-			<view class="btn" @click="examBank()" :class="{disabled:state}">开始考试</view>
+			<view class="btn" @click="examBank()" :class="{disabled:!((nowTime > start) && (nowTime < end ))}">开始考试</view>
 		</view>
 	</view>
 </template>
@@ -21,17 +21,61 @@ export default {
 	data() {
 		return {
 			state:1,
+			start:0,
+			timer:null,
+			timeText:'',
+			nowTime:0,
+			timeLimit:0,
+			examId:0,
+			eachExamId:0,
 		};
 	},
-	onLoad(){
+	onLoad(option){
+		this.eachExamId = option.eachExamId
+		this.examId = option.examId
+		this.timeLimit = +option.timeLimit || 0
+		this.start = +option.start;
+		this.end = (this.timeLimit* 60) + this.start ;
+		this.timer = setInterval(() => {
+			this.timeText = this.getDuring()
+		},1000)
 	},
 	onShow() {
+		clearInterval(this.timer)
+		this.timer = setInterval(() => {
+			this.timeText = this.getDuring()
+		},1000)
+	},
+	onUnload() {
+		clearInterval(this.timer)
 	},
 	methods: {
+		getDuring() {
+			this.nowTime = +this.$method.timest();
+			let during = this.start - this.nowTime;
+			if(during <= 0) {
+				return '00:00'
+			}
+			
+			let minutes = parseInt(during/60) >= 10 ? '0'+ parseInt(during/60) : parseInt(during/60);
+			let seconds = during % 60 >= 10 ? during % 60 :'0'+ during % 60;
+			
+			return minutes+':'+seconds
+		},
+		canTest() {
+			
+		},
 		examBank() {
-			uni.navigateTo({
-				url:'../examReport/index'
-			})
+			// if(((this.nowTime > this.start) && (this.nowTime < this.end ))) {
+				uni.navigateTo({
+					url:'../examBank/index?examId='+this.examId+'&eachExamId='+this.eachExamId
+				})
+			// } else {
+			// 	uni.showToast({
+			// 		icon:'none',
+			// 		title:'不在考试时间'
+			// 	})
+			// }
 		}
 	},
 	onReachBottom() {},

+ 76 - 38
pages5/examList/index.vue

@@ -2,10 +2,10 @@
 	<view>
 		<nav-bar title="模考预约" class="nav"></nav-bar>
 		<view class="tabs">
-			<view class="tab" :class="{ active: index == 0 }" data-index="1" @click="tab(0)">
+			<view class="tab" :class="{ active: param.mockStatus == 0 }" data-index="1" @click="tab(0)">
 				<view>未考试</view>
 			</view>
-			<view class="tab" :class="{ active: index == 1 }" data-index="2" @click="tab(1)">
+			<view class="tab" :class="{ active:  param.mockStatus == 1 }" data-index="2" @click="tab(1)">
 				<view>已结束</view>
 			</view>
 			<view class="sort" @click="showSort = true">
@@ -15,59 +15,61 @@
 		
 		
 		<view class="record">
-			<template v-if="index == 0">
-				<view class="examList" v-for="(item,index) in 5" :key="index">
+			<template v-if=" param.mockStatus == 0">
+				<view class="examList" v-for="(item,index) in recordList" :key="index">
 					<view class="main">
 						<view class="top" @click="showDetails(item)">
-							<view class="subject">2022年考前一建模拟考试</view>
+							<view class="subject">{{item.applyName}}</view>
 						</view>
 						<view class="item">
 							<view class="left">项目</view>
-							<view class="right">一级建造师</view>
+							<view class="right">{{ item.businessName }} {{item.projectName}}</view>
 						</view>
 						<view class="item">
 							<view class="left">专业</view>
-							<view class="right">市政专业</view>
+							<view class="right">{{item.categoryName}}</view>
 						</view>
 						<view class="item">
 							<view class="left">科目</view>
-							<view class="right">建设工程经济</view>
+							<view class="right">{{item.subjectName}}</view>
 						</view>
 						<view class="item">
 							<view class="left">考试时间</view>
 							<view class="right">
-								2022/4/15  9:00-10:00
+								{{ $method.timestampToTime(item.applySiteExamTime) }}
+								{{ item.applySiteStartTime }} - {{ item.applySiteEndTime }}
 							</view>
 						</view>
 						<view class="btn-wrap">
-							<view class="btn" :class="{disabled:index%2 == 0}" @click="goExamCount()">去考试</view>
+							<view class="btn" :class="{disabled:goTest(item)}" @click="goExamCount(item)">去考试</view>
 						</view>
 					</view>
 				</view>
 			</template>
 			
-			<template v-if="index == 1">
-				<view class="examList" v-for="(item,index) in 5" :key="index">
+			<template v-if=" param.mockStatus == 1">
+				<view class="examList" v-for="(item,index) in recordList" :key="index">
 					<view class="main">
 						<view class="top" @click="showDetails(item)">
-							<view class="subject">2022年考前一建模拟考试</view>
+							<view class="subject">{{item.applyName}}</view>
 						</view>
 						<view class="item">
 							<view class="left">项目</view>
-							<view class="right">一级建造师</view>
+							<view class="right">{{ item.businessName }} {{item.projectName}}</view>
 						</view>
 						<view class="item">
 							<view class="left">专业</view>
-							<view class="right">市政专业</view>
+							<view class="right">{{item.categoryName}}</view>
 						</view>
 						<view class="item">
 							<view class="left">科目</view>
-							<view class="right">建设工程经济</view>
+							<view class="right">{{item.subjectName}}</view>
 						</view>
 						<view class="item">
 							<view class="left">考试时间</view>
 							<view class="right">
-								2022/4/15  9:00-10:00
+								{{ $method.timestampToTime(item.applySiteExamTime) }}
+								{{ item.applySiteStartTime }} - {{ item.applySiteEndTime }}
 							</view>
 						</view>
 						
@@ -95,11 +97,11 @@
 					<view class="item__title">考试时间</view>
 					<view class="item__box">
 						<view class="text">
-							<picker mode="date" :value="dateFrom" :start="startDate" :end="endDate" @change="bindDateFromChange">
+							<picker mode="date"  :value="param.startTime" :end="endDate" @change="bindDateFromChange">
 								<view class="uni-input">{{dateFrom}}</view>
 							</picker>
 							- 
-							<picker mode="date" :value="dateTo" :start="startDate" :end="endDate" @change="bindDateToChange">
+							<picker mode="date" :value="param.endTime" :end="endDate"  @change="bindDateToChange">
 								<view class="uni-input">{{dateTo}}</view>
 							</picker>
 						</view>
@@ -136,7 +138,10 @@ export default {
 			goodsData: {},
 			param: {
 				pageNum: 1,
-				pageSize: 10
+				pageSize: 10,
+				mockStatus:0,
+				endTime:'',
+				startTime:'',
 			},
 			dateFrom:'',
 			dateTo:'',
@@ -152,13 +157,13 @@ export default {
 		};
 	},
 	onLoad(option) {
-		this.index = option.state || 0
+		this.param.mockStatus = option.state || 0
 		
 		this.dateFrom = this.$method.timestampToTime(new Date().getTime() / 1000).replace(/-/g,'/');
 		this.dateTo = this.$method.timestampToTime(new Date().getTime() / 1000).replace(/-/g,'/');
 		this.endDate = this.$method.timestampToTime(new Date().getTime() / 1000).replace(/-/g,'/');
 			
-		
+		this.mockSubscribeListSubscribe();
 		uni.getSystemInfo({
 			success:(e) => {
 				let info = uni.createSelectorQuery().select(".nav");
@@ -176,19 +181,18 @@ export default {
 	},
 	onPullDownRefresh() {
 		let that = this;
-		this.param = {
-			pageNum: 1,
-			pageSize: 10
-		};
-		this.getExamRecordList();
+		this.param.pageNum = 1;
+		this.mockSubscribeListSubscribe();
 		setTimeout(function() {
 			uni.stopPullDownRefresh();
 		}, 500);
 	},
 	onReachBottom() {
+		console.log(this.total,'total');
+		console.log(this.recordList.length,'length')
 		if (this.recordList.length < this.total) {
 			this.param.pageNum++;
-			this.getExamRecordList();
+			this.mockSubscribeListSubscribe();
 		}
 	},
 	onShow() {
@@ -202,6 +206,27 @@ export default {
 		
 	},
 	methods: {
+		goTest(item) {
+			let nowTime = +this.$method.timest();
+			let startTime = this.$method.TimeTotimestamp(this.$method.timestampToTime(item.applySiteExamTime) + ' ' + item.applySiteStartTime)
+			let canGo = (startTime-nowTime) <= (600) && (startTime-nowTime) >= (-(item.timeLimit * 60)  || 0)
+			
+			return !canGo
+		},
+		mockSubscribeListSubscribe() {
+			let param = JSON.parse(JSON.stringify(this.param))
+			if(param.endTime) {
+				param.endTime = this.$method.TimeTotimestamp(param.endTime)
+			}
+			
+			if(param.startTime) {
+				param.startTime = this.$method.TimeTotimestamp(param.startTime)
+			}
+			this.$api.mockSubscribeListSubscribe(param).then(res => {
+				this.recordList.push(...res.data.rows)
+				this.total = res.data.total
+			})
+		},
 		refreshByIndex() {
 			this.$api.examRecordGroupList({
 				pageNum: this.itemIndex+1,
@@ -212,9 +237,16 @@ export default {
 			});
 		},
 		
-		goExamCount() {
+		goExamCount(item) {
+			if(this.goTest(item)) {
+				uni.showToast({
+					icon:'none',
+					title:'不在考试时间'
+				})
+				return;
+			}
 			uni.navigateTo({
-				url:'../examCount/index'
+				url:'../examCount/index?start='+this.$method.TimeTotimestamp(this.$method.timestampToTime(item.applySiteExamTime) + ' ' + item.applySiteStartTime)+'&limit='+item.timeLimit+'&examId='+item.examId+'&eachExamId='+item.eachExamId
 			})
 		},
 		
@@ -225,25 +257,31 @@ export default {
 		appoint(item) {
 			this.appointModal = true;
 		},
-		tab(index) {
-			console.log(index,this.index)
-			if(this.index == index) {
-				this.index = 0;
+		tab(state) {
+			if(this.param.mockStatus == state) {
 				return;
 			}
-			this.index = index;
-			console.log(this.index);
+			this.recordList = [];
+			this.param.pageNum = 1;
+			this.param.mockStatus = state;
+			this.mockSubscribeListSubscribe()
 		},
 		bindDateFromChange(e) {
 			this.dateFrom = e.detail.value
 		},
 		
 		bindDateToChange(e) {
-			this.dateTo = e.detail.value
+				this.param.startTime = e.detail.value
+				this.param.pageNum = 1;
+				this.recordList = []
+				this.mockSubscribeListSubscribe();
 		},
 		
 		bindTitleChange(e) {
-			this.titleName = this.rangeArr[e.detail.value]
+				this.param.startTime = e.detail.value
+				this.param.pageNum = 1;
+				this.recordList = []
+				this.mockSubscribeListSubscribe();
 		}
 	}
 };

+ 15 - 54
pages5/examReport/index.vue

@@ -46,27 +46,21 @@
 				<navigator
 					 v-if="wrongRecordWrongNum != 0"
 					:url="
-						'/pages2/bank/questionBankWrongExplain?recordId=' + reportdata.recordId+'&id='+examData.examId
+						'/pages5/examReport/questionBankWrongExplain?recordId=' + reportdata.recordId+'&id='+examData.examId+'&eachExamId='+eachExamId
 					"
 				>
 					<view class="btnACs">错题解析</view>
 				</navigator>
 				<navigator
 					:url="
-						'/pages2/bank/questionBankAllExplain?id=' +
+						'/pages5/examReport/questionBankAllExplain?id=' +
 							reportdata.examId +
-							'&goodsid=' +
-							reportdata.goodsId +
-							'&moduleId=' +
-							reportdata.moduleExamId +
-							'&chapterId=' +
-							reportdata.chapterExamId +
-							'&recordId='+ reportdata.recordId
+							'&recordId='+ reportdata.recordId +
+							'&eachExamId='+eachExamId
 					"
 				>
 					<view class="btnACs">全部解析</view>
 				</navigator>
-				<view class="btnACs">去做题</view>
 			</view>
 		</view>
 		<view class="bottom">
@@ -135,14 +129,11 @@ export default {
 			reportdata: {},
 			examData:{},
 			examId:'',
-			moduleId:'',
-			goodsId:'',
 			chapterId:'',
 			context1: null,
 			context2: null,
-			nextExamId:'',
-			wrongRecordWrongNum:'',
-			orderGoodsId:'',
+			eachExamId:'',
+			wrongRecordWrongNum:0
 		};
 	},
 	onUnload() {},
@@ -154,17 +145,13 @@ export default {
 		
 	async onLoad(option) {
 		console.log(option)
-		this.orderGoodsId = option.orderGoodsId
 		this.recordId = option.id;
 		this.examId = option.examId;
-		this.moduleId = option.moduleId || 0;
-		this.chapterId = option.chapterId || 0;
-		this.goodsId = option.goodsId || '';
+		this.eachExamId = option.eachExamId
 		
-		this.examWrongRecordWrongNum();
-		this.bankExamNextExam()
+		this.mockWrongRecordWrongNum();
 		await this.bankExam();
-		await this.examReport();
+		await this.mockReport();
 		
 		uni.getSystemInfo({
 			success: res => {
@@ -257,33 +244,7 @@ export default {
 		
 	},
 	methods: {
-		bankExamNextExam() {
-			this.$api.bankExamNextExam({
-				chapterExamId:this.chapterId,
-				examId:this.examId,
-				goodsId:this.goodsId,
-				orderGoodsId:this.orderGoodsId,
-				moduleExamId:this.moduleId
-			}).then(res => {
-				if(res.data.code == 500) {
-					this.nextExamId = '';
-				} else if(res.data.code == 200) {
-					this.nextExamId = res.data.data.examId;
-				}
-			})
-		},
-		backBank() {
-			uni.navigateTo({
-				url: '/pages2/bank/questionBank?orderGoodsId='+orderGoodsId+'&id=' +this.nextExamId + '&goodsid=' + this.goodsId + '&moduleId=' + this.moduleId + '&chapterId=' + this.chapterId + ''
-			});
-			
-			// uni.navigateBack({
-			// 	delta:1
-			// })
-			// uni.redirectTo({
-			// 	url: '/pages2/bank/my_question'
-			// });
-		},
+		
 		bankExam(){
 			return new Promise(resolve =>{
 				this.$api.bankExam(this.examId).then(res => {
@@ -309,7 +270,7 @@ export default {
 			var prepage = pages[pages.length - 2]; //上一个页面
 			prepage.$vm.isRepeat = true;
 			uni.redirectTo({
-				url: '/pages2/bank/questionBank?orderGoodsId='+this.orderGoodsId+'&id=' + id + '&goodsid=' + goodsId + '&moduleId=' + moduleId + '&chapterId=' + chapterId + ''
+				url: '/pages5/examReport/questionBank?orderGoodsId='+this.orderGoodsId+'&id=' + id + '&goodsid=' + goodsId + '&moduleId=' + moduleId + '&chapterId=' + chapterId + ''
 			});
 		},
 		/**
@@ -323,9 +284,9 @@ export default {
 				});
 			});
 		},
-		examWrongRecordWrongNum() {
+		mockWrongRecordWrongNum() {
 			return new Promise(resolve => {
-				this.$api.examWrongRecordWrongNum(this.recordId).then(res => {
+				this.$api.mockWrongRecordWrongNum(this.recordId).then(res => {
 					this.wrongRecordWrongNum = res.data.data || 0;
 					resolve();
 				});
@@ -354,9 +315,9 @@ export default {
 				});
 			});
 		},
-		examReport() {
+		mockReport() {
 			return new Promise(resolve => {
-				this.$api.examReport(this.recordId).then(res => {
+				this.$api.mockReport(this.recordId).then(res => {
 					this.reportdata = res.data.data;
 					resolve()
 				});

+ 1276 - 0
pages5/examReport/questionBankAllExplain.vue

@@ -0,0 +1,1276 @@
+<template>
+  <view class="questionBank">
+    <nav-bar title="全部解析"></nav-bar>
+    <swiper
+      class="swiper"
+      :current="current"
+      @change="swiperChange"
+      :interval="interval"
+    >
+      <swiper-item v-for="(bank, bankIndex) in questionList" :key="bankIndex">
+        <view class="pageContent">
+          <view class="pad_8 titBox">
+            <view class="firstLetter">
+              <view class="leftLetters">
+                <view class="btnType">
+                  <text v-if="bank.type == 1">单选</text>
+                  <text v-if="bank.type == 2">多选</text>
+                  <text v-if="bank.type == 3">判断</text>
+                  <text v-if="bank.type == 4">案例</text>
+                  <text v-if="bank.type == 5">简答</text>
+                </view>
+                <text>{{ bankIndex + 1 }}/{{ questionList.length }}</text>
+              </view>
+              <view style="color: #666; font-size: 28rpx"></view>
+              <view class="leftLetters"></view>
+            </view>
+            <view class="titles"
+              ><rich-text :nodes="bank.content"></rich-text
+            ></view>
+          </view>
+          <template v-if="bank.type == 1">
+            <view class="pad_8 titBox no-margin">
+              <view v-if="!bank.ques">
+                <view
+                  v-for="(item, index) in bank.jsonStr"
+                  :key="index"
+                  class="lisSty"
+                >
+                  <view class="activeTI">{{ ast[index] }}</view>
+                  <view class="flex_auto">
+                    {{ item.content }}
+                    <view v-if="item.imgUrl">
+                      <image
+                        style="width: 600rpx"
+                        mode="widthFix"
+                        :src="$method.splitImgHost(item.imgUrl)"
+                      ></image>
+                    </view>
+                  </view>
+                </view>
+              </view>
+              <view v-if="bank.ques">
+                <view
+                  v-for="(item, index) in bank.jsonStr"
+                  :key="index"
+                  class="lisSty"
+                >
+                  <text
+                    :class="{
+                      right:
+                        item.optionsId == bank.ques ||
+                        item.optionsId == bank.ans,
+                      wrong:
+                        item.optionsId == bank.ques && bank.ques != bank.ans,
+                    }"
+                    class="activeTI"
+                    >{{ ast[index] }}</text
+                  >
+                  <view class="flex_auto">
+                    {{ item.content }}
+                    <view v-if="item.imgUrl">
+                      <image
+                        style="width: 600rpx"
+                        mode="widthFix"
+                        :src="$method.splitImgHost(item.imgUrl)"
+                      ></image>
+                    </view>
+                  </view>
+                </view>
+              </view>
+            </view>
+            <view>
+              <view class="pad_8 answer">
+                <view>正确答案:{{ ast[bank.ans - 1] }}</view>
+                <view>我的答案:{{ ast[bank.ques - 1] || "" }}</view>
+              </view>
+              <view class="pad_8 answerInfos">
+                <view class="answerTitle">答案解析</view>
+                <view class="answerContent">
+                  <rich-text :nodes="bank.analysisContent"></rich-text>
+                </view>
+              </view>
+            </view>
+          </template>
+
+          <template v-if="bank.type == 2">
+            <view class="pad_8 titBox no-margin">
+              <view v-if="!bank.ques">
+                <view
+                  v-for="(item, index) in bank.jsonStr"
+                  :key="index"
+                  class="lisSty"
+                >
+                  <view :class="{ checked: item.checked }" class="activeTI">{{
+                    ast[index]
+                  }}</view>
+                  <view class="flex_auto">
+                    {{ item.content }}
+                    <view v-if="item.imgUrl">
+                      <image
+                        style="width: 600rpx"
+                        mode="widthFix"
+                        :src="$method.splitImgHost(item.imgUrl)"
+                      ></image>
+                    </view>
+                  </view>
+                </view>
+              </view>
+              <view v-if="bank.ques">
+                <view
+                  v-for="(item, index) in bank.jsonStr"
+                  :key="index"
+                  class="lisSty"
+                >
+                  <text
+                    :class="{
+                      right:
+                        (bank.ques &&
+                          bank.ques.indexOf(item.optionsId) != -1) ||
+                        (bank.ans && bank.ans.indexOf(item.optionsId) != -1),
+                      wrong:
+                        bank.ques &&
+                        bank.ques.indexOf(item.optionsId) != -1 &&
+                        bank.ans &&
+                        bank.ans.indexOf(item.optionsId) == -1,
+                    }"
+                    class="activeTI"
+                    >{{ ast[index] }}</text
+                  >
+                  <view class="flex_auto">
+                    {{ item.content }}
+                    <view v-if="item.imgUrl">
+                      <image
+                        style="width: 600rpx"
+                        mode="widthFix"
+                        :src="$method.splitImgHost(item.imgUrl)"
+                      ></image>
+                    </view>
+                  </view>
+                </view>
+              </view>
+            </view>
+            <view>
+              <view class="pad_8 answer">
+                <view
+                  >正确答案:
+                  <text
+                    :key="ansItemIndex"
+                    v-for="(ansItem, ansItemIndex) in bank.ans"
+                    >{{ ast[ansItem - 1] }}</text
+                  >
+                </view>
+                <view
+                  >我的答案:
+                  <text
+                    :key="quesItemIndex"
+                    v-for="(quesItem, quesItemIndex) in bank.ques"
+                    >{{ ast[quesItem - 1] }}</text
+                  >
+                </view>
+              </view>
+              <view class="pad_8 answerInfos">
+                <view class="answerTitle">答案解析</view>
+                <view class="answerContent">
+                  <rich-text :nodes="bank.analysisContent"></rich-text>
+                </view>
+              </view>
+            </view>
+          </template>
+
+          <template v-if="bank.type == 3">
+            <view class="pad_8 titBox no-margin">
+              <view v-if="!bank.ques">
+                <view
+                  v-for="(item, index) in judge"
+                  :key="index"
+                  class="lisSty"
+                >
+                  <view class="activeTI">{{ ast[index] }}</view>
+                  <view class="flex_auto">
+                    {{ item }}
+                    <view v-if="item.imgUrl">
+                      <image
+                        style="width: 600rpx"
+                        mode="widthFix"
+                        :src="$method.splitImgHost(item.imgUrl)"
+                      ></image>
+                    </view>
+                  </view>
+                </view>
+              </view>
+              <view v-if="bank.ques">
+                <view
+                  v-for="(item, index) in judge"
+                  :key="index"
+                  class="lisSty"
+                >
+                  <text
+                    :class="{
+                      right: index == bank.ques || index == bank.ans,
+                      wrong: index == bank.ques && bank.ques != bank.ans,
+                    }"
+                    class="activeTI"
+                    >{{ ast[index] }}</text
+                  >
+                  <view class="flex_auto">
+                    {{ item }}
+                    <view v-if="item.imgUrl">
+                      <image
+                        style="width: 600rpx"
+                        mode="widthFix"
+                        :src="$method.splitImgHost(item.imgUrl)"
+                      ></image>
+                    </view>
+                  </view>
+                </view>
+              </view>
+            </view>
+            <view>
+              <view class="pad_8 answer">
+                <view>正确答案:{{ ast[bank.ans] }}</view>
+                <view>我的答案:{{ ast[bank.ques] || "" }}</view>
+              </view>
+              <view class="pad_8 answerInfos">
+                <view class="answerTitle">答案解析</view>
+                <view class="answerContent">
+                  <rich-text :nodes="bank.analysisContent"></rich-text>
+                </view>
+              </view>
+            </view>
+          </template>
+
+          <!-- 简答题 -->
+          <template v-if="bank.type == 5">
+            <view class="pad_8 titBox">
+              <view class="ans">
+                <view class="ans_submit answerInfos">
+                  <view class="answerTitle">我的答案:</view>
+                  {{ bank.ques.text || "" }}
+                  <view class="imgs">
+                    <image
+                      class="img"
+                      v-for="(ques, quesIndex) in bank.ques.imageList"
+                      :key="quesIndex"
+                      :src="$method.splitImgHost(ques, true)"
+                    ></image>
+                  </view>
+                </view>
+              </view>
+            </view>
+            <view>
+              <view class="pad_8 answerInfos">
+                <view class="answerTitle">答案解析:</view>
+                <view class="answerContent">
+                  <rich-text :nodes="bank.analysisContent"></rich-text>
+                </view>
+              </view>
+            </view>
+          </template>
+
+          <!-- 案例题 -->
+          <template v-if="bank.type == 4">
+            <view class="tabs">
+              <view
+                class="tab"
+                :class="{ current: tabIndex == bank.current }"
+                :key="tabIndex"
+                v-for="(tab, tabIndex) in bank.jsonStr"
+                @click="tabSelect(tabIndex, bankIndex)"
+              >
+                问题{{ tabIndex + 1 }}
+              </view>
+            </view>
+            <view
+              v-for="(ansItem, ansIndex) in bank.jsonStr"
+              v-if="bank.current == ansIndex"
+              :key="ansIndex"
+            >
+              <template v-if="ansItem.type == 1">
+                <view class="pad_8 titBox">
+                  <view class="leftLetters">
+                    <view class="btnType">
+                      <text>单选</text>
+                    </view>
+                  </view>
+                  <view class="titles">
+                    <rich-text :nodes="ansItem.content"></rich-text>
+                  </view>
+                  <view v-if="!bank.ques[ansIndex]">
+                    <view
+                      v-for="(option, childIndex) in ansItem.optionsList"
+                      :key="childIndex"
+                      class="lisSty"
+                    >
+                      <view class="activeTI">{{ ast[childIndex] }}</view>
+                      <view class="flex_auto">
+                        <rich-text
+                          class="textChild"
+                          :nodes="option.content"
+                        ></rich-text>
+                        <view v-if="option.imgUrl">
+                          <image
+                            style="width: 600rpx"
+                            mode="widthFix"
+                            :src="$method.splitImgHost(option.imgUrl)"
+                          ></image>
+                        </view>
+                      </view>
+                    </view>
+                  </view>
+                  <view v-if="bank.ques[ansIndex]">
+                    <view
+                      v-for="(option, childIndex) in ansItem.optionsList"
+                      :key="childIndex"
+                      class="lisSty"
+                    >
+                      <text
+                        :class="{
+                          right:
+                            option.optionsId == bank.ques[ansIndex] ||
+                            option.optionsId == bank.ans[ansIndex],
+                          wrong:
+                            option.optionsId == bank.ques[ansIndex] &&
+                            bank.ques[ansIndex] != bank.ans[ansIndex],
+                        }"
+                        class="activeTI"
+                        >{{ ast[childIndex] }}</text
+                      >
+                      <view class="flex_auto">
+                        <rich-text :nodes="option.content"></rich-text>
+                        <view v-if="option.imgUrl">
+                          <image
+                            style="width: 600rpx"
+                            mode="widthFix"
+                            :src="$method.splitImgHost(option.imgUrl)"
+                          ></image>
+                        </view>
+                      </view>
+                    </view>
+                  </view>
+                </view>
+                <view>
+                  <view class="pad_8 answer">
+                    <view>正确答案:{{ ast[bank.ans[ansIndex] - 1] }}</view>
+                    <view
+                      >我的答案:{{ ast[bank.ques[ansIndex] - 1] || "" }}</view
+                    >
+                  </view>
+                  <view class="pad_8 answerInfos">
+                    <view class="answerTitle">答案解析</view>
+                    <view class="answerContent">
+                      <rich-text :nodes="option.analysisContent"></rich-text>
+                    </view>
+                  </view>
+                </view>
+              </template>
+
+              <template v-if="ansItem.type == 2">
+                <view class="pad_8 titBox">
+                  <view class="leftLetters">
+                    <view class="btnType">
+                      <text>多选</text>
+                    </view>
+                  </view>
+                  <view class="titles">
+                    <rich-text :nodes="ansItem.content"></rich-text>
+                    <view v-if="option.imgUrl">
+                      <image
+                        style="width: 600rpx"
+                        mode="widthFix"
+                        :src="$method.splitImgHost(option.imgUrl)"
+                      ></image>
+                    </view>
+                  </view>
+                  <view v-if="!bank.ques[ansIndex]">
+                    <view
+                      v-for="(option, childindex) in ansItem.optionsList"
+                      :key="childindex"
+                      class="lisSty"
+                    >
+                      <view
+                        :class="{ checked: option.checked }"
+                        class="activeTI"
+                        >{{ ast[childindex] }}</view
+                      >
+                      <view class="flex_auto">
+                        <rich-text :nodes="option.content"></rich-text>
+                        <view v-if="option.imgUrl">
+                          <image
+                            style="width: 600rpx"
+                            mode="widthFix"
+                            :src="$method.splitImgHost(option.imgUrl)"
+                          ></image>
+                        </view>
+                      </view>
+                    </view>
+                  </view>
+                  <view v-if="bank.ques && bank.ques[ansIndex]">
+                    <view
+                      v-for="(option, childindex) in ansItem.optionsList"
+                      :key="childindex"
+                      class="lisSty"
+                    >
+                      <text
+                        :class="{
+                          right: right(bankIndex, ansIndex, option),
+                          wrong: wrong(bankIndex, ansIndex, option),
+                        }"
+                        class="activeTI"
+                        >{{ ast[childindex] }}</text
+                      >
+                      <view class="flex_auto">
+                        <rich-text :nodes="option.content"></rich-text>
+                      </view>
+                    </view>
+                  </view>
+                </view>
+                <view>
+                  <view class="pad_8 answer">
+                    <view
+                      >正确答案:
+                      <text
+                        :key="ansItemIndex1"
+                        v-for="(ansItem1, ansItemIndex1) in bank.ans[ansIndex]"
+                        >{{ ast[ansItem1 - 1] }}</text
+                      >
+                    </view>
+                    <view
+                      >我的答案:
+                      <text
+                        :key="quesItemIndex"
+                        v-for="(quesItem, quesItemIndex) in bank.ques[ansIndex]"
+                        >{{ ast[quesItem - 1] }}</text
+                      >
+                    </view>
+                  </view>
+                  <view class="pad_8 answerInfos">
+                    <view class="answerTitle">答案解析</view>
+                    <view class="answerContent">
+                      <rich-text :nodes="ansItem.analysisContent"></rich-text>
+                    </view>
+                  </view>
+                </view>
+              </template>
+
+              <template v-if="ansItem.type == 3">
+                <view class="pad_8 titBox">
+                  <view class="leftLetters">
+                    <view class="btnType">
+                      <text>判断</text>
+                    </view>
+                  </view>
+                  <view class="titles">
+                    <rich-text :nodes="ansItem.content"></rich-text>
+                  </view>
+                  <view v-if="!bank.ques[ansIndex]">
+                    <view
+                      v-for="(option, childindex) in judge"
+                      :key="childindex"
+                      class="lisSty"
+                    >
+                      <view class="activeTI">{{ ast[childindex] }}</view>
+
+                      <view class="flex_auto">
+                        {{ option }}
+                        <view v-if="option.imgUrl">
+                          <image
+                            style="width: 600rpx"
+                            mode="widthFix"
+                            :src="$method.splitImgHost(option.imgUrl)"
+                          ></image>
+                        </view>
+                      </view>
+                    </view>
+                  </view>
+                  <view v-if="bank.ques[ansIndex]">
+                    <view
+                      v-for="(option, childindex) in judge"
+                      :key="childindex"
+                      class="lisSty"
+                    >
+                      <text
+                        :class="{
+                          right:
+                            childindex == bank.ques[ansIndex] ||
+                            childindex == bank.ans[ansIndex],
+                          wrong:
+                            childindex == bank.ques[ansIndex] &&
+                            bank.ques[ansIndex] != bank.ans[ansIndex],
+                        }"
+                        class="activeTI"
+                        >{{ ast[childindex] }}</text
+                      >
+                      <view class="flex_auto">
+                        {{ option }}
+                        <view v-if="option.imgUrl">
+                          <image
+                            style="width: 600rpx"
+                            mode="widthFix"
+                            :src="$method.splitImgHost(option.imgUrl)"
+                          ></image>
+                        </view>
+                      </view>
+                    </view>
+                  </view>
+                </view>
+                <view>
+                  <view class="pad_8 answer">
+                    <view>正确答案:{{ ast[bank.ans[ansIndex]] }}</view>
+                    <view>我的答案:{{ ast[bank.ques[ansIndex]] || "" }}</view>
+                  </view>
+                  <view class="pad_8 answerInfos">
+                    <view class="answerTitle">答案解析</view>
+                    <view class="answerContent">
+                      <rich-text :nodes="ansItem.analysisContent"></rich-text>
+                    </view>
+                  </view>
+                </view>
+              </template>
+
+              <!-- 简答题 -->
+              <template v-if="ansItem.type == 5">
+                <view class="pad_8 titBox_title">
+                  <view class="leftLetters">
+                    <view class="btnType">
+                      <text>简答</text>
+                    </view>
+                  </view>
+                  <view class="titles">
+                    <rich-text :nodes="ansItem.content"></rich-text>
+                  </view>
+                </view>
+                <view class="pad_8 titBox_title">
+                  <view class="ans">
+                    <view class="ans_submit answerInfos">
+                      <view class="answerTitle">我的答案</view>
+                      {{
+                        (bank.ques[ansIndex] && bank.ques[ansIndex].text) || ""
+                      }}
+                      <view
+                        class="imgs"
+                        v-if="
+                          bank.ques[ansIndex] &&
+                          bank.ques[ansIndex].imageList.length
+                        "
+                      >
+                        <image
+                          class="img"
+                          :key="quesIndex"
+                          v-for="(ques, quesIndex) in bank.ques[ansIndex]
+                            .imageList"
+                          :src="$method.splitImgHost(ques, true)"
+                        ></image>
+                      </view>
+                    </view>
+                  </view>
+                </view>
+                <view>
+                  <view class="pad_8 answerInfos">
+                    <view class="answerTitle">答案解析</view>
+                    <view class="answerContent">
+                      <rich-text :nodes="ansItem.analysisContent"></rich-text>
+                    </view>
+                  </view>
+                </view>
+              </template>
+            </view>
+          </template>
+
+          <view class="footer_btn">
+            <view
+              class="collect"
+              @click="collect(collectList[bankIndex], bankIndex)"
+            >
+              <view>
+                <image src="/static/icon/collect.png" mode=""></image>
+                <view>收藏</view>
+              </view>
+            </view>
+            <view class="flex_center" @click="openFooterTab">
+              <view class="up-icon">
+                <image src="/static/up.png"></image>
+              </view>
+              答题卡
+            </view>
+            <view class="collect" @click="pdsubmit">
+              <view>
+                <image src="/static/jj.png" mode=""></image>
+                <view>交卷</view>
+              </view>
+            </view>
+          </view>
+        </view>
+      </swiper-item>
+    </swiper>
+
+    <u-popup v-model="show" mode="bottom" border-radius="14" height="680rpx">
+      <view class="popupView">
+        <view class="popupTops">
+          <view class="topIcon"></view>
+          点击编号即可跳转至对应题目
+        </view>
+        <view class="popupContent">
+          <scroll-view scroll-y="true" style="height: 506rpx">
+            <view class="boxSty">
+              <view
+                v-for="(item, index) in questionList"
+                :key="index"
+                @click="changeIndex(index)"
+                :class="{
+                  isRight: isRight(item, index),
+                  isWrong: isWrong(item, index),
+                  isPart: isPart(item, index),
+                }"
+                class="liListSty"
+                >{{ index + 1 }}</view
+              >
+            </view>
+          </scroll-view>
+        </view>
+      </view>
+    </u-popup>
+
+    <view class="dialog" v-if="showDialog">
+      <view class="text">左右滑动切换上下题</view>
+      <view class="btn" @click="hideDialog">我知道了</view>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      id: "",
+      current: 0,
+      questionList: [],
+      ast: ["A", "B", "C", "D", "E", "F", "G"],
+      judge: ["错误", "正确"],
+      show: false,
+      showDialog: false,
+      bankList: [],
+      recordId: "",
+    };
+  },
+  onLoad(option) {
+    this.id = option.id || "";
+    this.recordId = option.recordId || "";
+
+    let showDialog = uni.getStorageSync("showDialog");
+
+    if (showDialog) {
+      this.showDialog = false;
+    } else {
+      this.showDialog = true;
+      uni.setStorageSync("showDialog", "1");
+    }
+    this.goodsQuestionList();
+  },
+  onUnload() {},
+  methods: {
+    /**
+     * 是否有上传图片
+     */
+    hasImgs(bank) {
+      return bank.ansText.imageList.length == 0;
+    },
+
+    goodsQuestionList() {
+      this.$api.mockReport(this.recordId).then((res) => {
+        this.questionList = JSON.parse(res.data.data.historyExamJson);
+      });
+    },
+
+    openFooterTab() {
+      this.show = true;
+    },
+    hideDialog() {
+      this.showDialog = false;
+    },
+    changeIndex(index) {
+      this.current = index;
+    },
+
+    swiperChange(e) {
+      this.current = e.detail.current;
+    },
+
+    isRight(item, index) {
+      //单选
+      if (this.questionList[index].ques) {
+        if (item.type == 1) {
+          return this.questionList[index].ques == this.questionList[index].ans;
+          //多选
+        } else if (item.type == 2) {
+          //每一项都相等
+          return this.questionList[index].ans.every((item, i) => {
+            return item == this.questionList[index].ques[i];
+          });
+          //判断
+        } else if (item.type == 3) {
+          return this.questionList[index].ques == this.questionList[index].ans;
+        } else {
+          return false;
+        }
+      } else {
+        return false;
+      }
+    },
+
+    right(bankIndex, ansIndex, option) {
+      if (
+        this.questionList[bankIndex].ques[ansIndex] &&
+        this.questionList[bankIndex].ans[ansIndex]
+      ) {
+        if (
+          this.questionList[bankIndex].ques[ansIndex].indexOf(
+            option.optionsId
+          ) != -1 ||
+          this.questionList[bankIndex].ans[ansIndex].indexOf(
+            option.optionsId
+          ) != -1
+        ) {
+          return true;
+        } else {
+          return false;
+        }
+      } else {
+        return false;
+      }
+    },
+
+    wrong(bankIndex, ansIndex, option) {
+      if (
+        this.questionList[bankIndex].ques[ansIndex] &&
+        this.questionList[bankIndex].ans[ansIndex]
+      ) {
+        if (
+          this.questionList[bankIndex].ques[ansIndex].indexOf(
+            option.optionsId
+          ) != -1 &&
+          this.questionList[bankIndex].ans[ansIndex].indexOf(
+            option.optionsId
+          ) == -1
+        ) {
+          return true;
+        } else {
+          return false;
+        }
+      } else {
+        return false;
+      }
+    },
+
+    isWrong(item, index) {
+      if (this.questionList[index].ques) {
+        //单选
+        if (item.type == 1) {
+          return this.questionList[index].ques != this.questionList[index].ans;
+          //多选
+        } else if (item.type == 2) {
+          //每一项都相等
+          return this.questionList[index].ques.some((item, i) => {
+            return this.questionList[index].ans.indexOf(item) == -1;
+          });
+          //判断
+        } else if (item.type == 3) {
+          return this.questionList[index].ques != this.questionList[index].ans;
+        } else {
+          return false;
+        }
+      } else {
+        return false;
+      }
+    },
+    isPart(item, index) {
+      if (this.questionList[index].ques) {
+        if (item.type == 2) {
+          let isWrong = this.questionList[index].ques.some((item, i) => {
+            return this.questionList[index].ans.indexOf(item) == -1;
+          });
+
+          let isRight = this.questionList[index].ans.every((item, i) => {
+            return item == this.questionList[index].ques[i];
+          });
+
+          if (!isRight && !isWrong) {
+            return true;
+          }
+        }
+      } else {
+        return false;
+      }
+    },
+
+    tabSelect(index, bankindex) {
+      this.$set(this.questionList[bankindex], "current", index);
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.questionBank {
+  width: 100%;
+  height: 100vh;
+  display: flex;
+  flex-direction: column;
+}
+.swiper {
+  width: 100%;
+  flex: 1;
+}
+.lisSty {
+  margin-bottom: 16rpx;
+  display: flex;
+  align-items: center;
+
+  .flex_auto {
+    flex: 1;
+  }
+}
+.activeTI {
+  vertical-align: middle;
+  display: inline-block;
+  border: 1rpx solid #eee;
+  border-radius: 50rpx;
+  height: 48rpx;
+  line-height: 46rpx;
+  text-align: center;
+  width: 48rpx;
+  margin-right: 15rpx;
+  color: #666;
+  font-size: 30rpx;
+
+  &.right {
+    color: #fff;
+    background: #36c75a;
+  }
+
+  &.wrong {
+    color: #fff;
+    background: #ff3b30;
+  }
+
+  &.checked {
+    color: #fff;
+    background: #007aff;
+  }
+}
+
+.submit_checkbox {
+  position: fixed;
+  left: 0;
+  right: 0;
+  bottom: 120rpx;
+  margin: 20rpx auto;
+  width: 526rpx;
+  height: 80rpx;
+  background: rgba(0, 122, 255, 1);
+  color: #fff;
+  text-align: center;
+  line-height: 80rpx;
+  font-size: 30rpx;
+  border-radius: 40rpx;
+}
+.titles {
+  overflow: hidden;
+  margin-bottom: 24rpx;
+}
+.titBox {
+  padding: 41rpx 25rpx 24rpx 25rpx;
+}
+
+.titBox_title {
+  padding: 21rpx;
+}
+
+.tabs {
+  margin: 10rpx;
+  display: flex;
+  .tab {
+    margin: 0 4rpx;
+    padding: 10rpx 13rpx;
+    text-align: center;
+    color: #007aff;
+    font-size: 28rpx;
+    border-radius: 16rpx;
+    background: #fff;
+
+    &.current {
+      color: #fff;
+      background: #007aff;
+    }
+  }
+}
+
+.ans {
+  margin: 8rpx 8rpx 8rpx;
+
+  .ans_input {
+    border-radius: 16rpx;
+    background: #fff;
+    .top {
+      border-bottom: 1rpx solid #eeeeee;
+      padding: 16rpx;
+      display: flex;
+      align-items: center;
+
+      .icon {
+        margin-right: 20rpx;
+        width: 40rpx;
+        height: 38rpx;
+      }
+
+      .progress {
+        flex: 1;
+      }
+
+      .submit {
+        width: 168rpx;
+        height: 48rpx;
+        line-height: 48rpx;
+        text-align: center;
+        color: #fff;
+        font-size: 30rpx;
+        background: #007aff;
+        border-radius: 24rpx;
+
+        &.disabled {
+          opacity: 0.6;
+        }
+      }
+    }
+
+    .textarea {
+      textarea {
+        width: 100%;
+        height: 287rpx;
+        padding: 10rpx;
+      }
+    }
+
+    .imgs {
+      overflow: hidden;
+      display: flex;
+      width: 100%;
+      .img {
+        width: 104rpx;
+        height: 104rpx;
+        border-radius: 8rpx;
+        position: relative;
+        margin: 20rpx;
+
+        text {
+          position: absolute;
+          right: -15rpx;
+          top: -15rpx;
+          width: 30rpx;
+          height: 30rpx;
+          text-align: center;
+          line-height: 30rpx;
+          color: #fff;
+          background: #ff3b30;
+          border-radius: 50%;
+        }
+
+        image {
+          width: 100%;
+          height: 100%;
+        }
+      }
+    }
+  }
+
+  .ans_submit {
+    padding: 16rpx;
+    border-radius: 16rpx;
+    background: #fff;
+
+    .imgs {
+      overflow: hidden;
+      display: flex;
+      width: 100%;
+      .img {
+        width: 104rpx;
+        height: 104rpx;
+        border-radius: 8rpx;
+        position: relative;
+        margin: 20rpx;
+
+        image {
+          width: 100%;
+          height: 100%;
+        }
+      }
+    }
+  }
+}
+.leftLetters {
+  display: flex;
+  align-items: center;
+  width: 220rpx;
+  .btnType {
+    padding: 5rpx 10rpx;
+    border: 1rpx solid #007aff;
+    border-radius: 10rpx;
+    background-color: rgba(0, 122, 255, 0.1);
+    font-size: 28rpx;
+    color: #007aff;
+    margin-right: 15rpx;
+  }
+}
+.firstLetter {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 30rpx;
+}
+.popupView {
+  height: 100%;
+  padding-bottom: 100rpx;
+  .popupTops {
+    height: 77rpx;
+    border-bottom: 1rpx solid #eee;
+    text-align: center;
+    line-height: 77rpx;
+    font-size: 24rpx;
+    color: #999;
+    position: relative;
+    .topIcon {
+      position: absolute;
+      top: 10rpx;
+      left: 50%;
+      transform: translateX(-50%);
+      width: 80rpx;
+      height: 8rpx;
+      background-color: #999;
+      border-radius: 4rpx;
+    }
+  }
+  .popupContent {
+  }
+}
+.pageContent {
+  position: relative;
+  background-color: #eaeef1;
+  height: 100%;
+  overflow-y: scroll;
+  padding-top: 8rpx;
+  padding-bottom: 100rpx;
+}
+.pad_8 {
+  background-color: #fff;
+  margin: 0rpx 8rpx 8rpx;
+  border-radius: 16rpx;
+
+  &.no-margin {
+    margin-top: -16rpx;
+    border-radius: 0 0 16rpx 16rpx;
+  }
+}
+.answer {
+  height: 80rpx;
+  line-height: 80rpx;
+  padding: 0rpx 24rpx;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  color: #666;
+  font-size: 30rpx;
+}
+.footer_btn {
+  background-color: #fff;
+  z-index: 10078;
+  position: fixed;
+  bottom: 0rpx;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  width: 100%;
+  height: 98rpx;
+  padding: 0rpx 38rpx;
+  border-top: 1rpx solid #eee;
+
+  .flex_center {
+    flex: 1;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    flex-direction: column;
+    margin: 0 200rpx;
+    font-size: 24rpx;
+    color: #999999;
+
+    .up-icon {
+      margin-bottom: 18rpx;
+      width: 100%;
+      display: flex;
+      justify-content: center;
+      image {
+        width: 58rpx;
+        height: 21rpx;
+      }
+    }
+  }
+
+  .collect {
+    visibility: hidden;
+    width: 100rpx;
+
+    &.show {
+      visibility: visible;
+    }
+
+    > view {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+
+      image {
+        width: 32rpx;
+        height: 32rpx;
+        margin-bottom: 6rpx;
+      }
+
+      view {
+        font-size: 24rpx;
+        color: #999999;
+      }
+    }
+  }
+}
+.boxSty {
+  padding: 44rpx 41rpx 0rpx;
+}
+.liListSty {
+  border: 1rpx solid #eeeeee;
+  width: 88rpx;
+  height: 88rpx;
+  border-radius: 32rpx;
+  text-align: center;
+  line-height: 88rpx;
+  color: #333;
+  font-size: 32rpx;
+  float: left;
+  margin: 20rpx 23rpx;
+
+  &.isRight {
+    border: 1rpx solid #eeeeee;
+    color: #fff;
+    background: #36c75a;
+  }
+
+  &.isWrong {
+    border: 1rpx solid #eeeeee;
+    color: #fff;
+    background: #ff3b30;
+  }
+
+  &.isPart {
+    border: 1rpx solid #eeeeee;
+    color: #fff;
+    background: #FFC53D;
+  }
+}
+.answerInfos {
+  padding: 25rpx 25rpx 25rpx 23rpx;
+}
+.answerTitle {
+  margin-bottom: 28rpx;
+  color: #666;
+  font-size: 30rpx;
+}
+.answerContent {
+  font-size: 30rpx;
+  color: #666;
+}
+
+.textChild {
+  display: inline-block;
+  vertical-align: middle;
+}
+
+.dialog {
+  position: fixed;
+  left: 0;
+  top: 0;
+  width: 100%;
+  height: 100%;
+  background-color: rgba(0, 0, 0, 0.8);
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  z-index: 20000;
+
+  .pointer {
+    width: 338rpx;
+    height: 240rpx;
+  }
+
+  .text {
+    font-size: 32rpx;
+    color: #ffffff;
+    text-align: center;
+  }
+
+  .btn {
+    width: 242rpx;
+    height: 82rpx;
+    border: 2rpx solid #ffffff;
+    border-radius: 16rpx;
+    text-align: center;
+    line-height: 82rpx;
+    margin: 41rpx auto;
+    color: #fff;
+    font-size: 32rpx;
+  }
+}
+.popboxs {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+}
+.classTops {
+  flex-shrink: 0;
+  padding: 39rpx 0rpx 4rpx;
+  font-weight: bold;
+  color: #333;
+  font-size: 30rpx;
+}
+.textStys {
+  width: 100%;
+  flex: 1;
+  padding: 36rpx;
+}
+.classFootsty {
+  flex-shrink: 0;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  padding: 10rpx 0rpx 40rpx;
+  .btnsty {
+    width: 200rpx;
+    height: 80rpx;
+    border-radius: 40rpx;
+    font-weight: bold;
+    font-size: 30rpx;
+    text-align: center;
+    line-height: 80rpx;
+  }
+  .btns1 {
+    background-color: #f5f5f5;
+    color: #007aff;
+  }
+  .btns2 {
+    margin-left: 40rpx;
+    background-color: #007aff;
+    color: #ffffff;
+  }
+}
+</style>

+ 1292 - 0
pages5/examReport/questionBankWrongExplain.vue

@@ -0,0 +1,1292 @@
+<template>
+  <view class="questionBank">
+    <nav-bar title="错题解析"></nav-bar>
+    <swiper
+      class="swiper"
+      :current="current"
+      @change="swiperChange"
+      :interval="interval"
+    >
+      <swiper-item v-for="(bank, bankIndex) in questionList" :key="bankIndex">
+        <view class="pageContent">
+          <view class="pad_8 titBox">
+            <view class="firstLetter">
+              <view class="leftLetters">
+                <view class="btnType">
+                  <text v-if="bank.type == 1">单选</text>
+                  <text v-if="bank.type == 2">多选</text>
+                  <text v-if="bank.type == 3">判断</text>
+                  <text v-if="bank.type == 4">案例</text>
+                  <text v-if="bank.type == 5">简答</text>
+                </view>
+                <text>{{ bankIndex + 1 }}/{{ questionList.length }}</text>
+              </view>
+              <view style="color: #666; font-size: 28rpx"></view>
+              <view class="leftLetters"></view>
+            </view>
+            <view class="titles">
+              <rich-text :nodes="bank.content"></rich-text>
+            </view>
+          </view>
+          <template v-if="bank.type == 1">
+            <view class="pad_8 titBox no-margin">
+              <view v-if="!bank.ques">
+                <view
+                  v-for="(item, index) in bank.jsonStr"
+                  :key="index"
+                  class="lisSty"
+                >
+                  <view class="activeTI">{{ ast[index] }}</view>
+                  <view class="flex_auto">
+                    {{ item.content }}
+                    <view v-if="item.imgUrl">
+                      <image
+                        style="width: 600rpx"
+                        mode="widthFix"
+                        :src="$method.splitImgHost(item.imgUrl)"
+                      ></image>
+                    </view>
+                  </view>
+                </view>
+              </view>
+              <view v-if="bank.ques">
+                <view
+                  v-for="(item, index) in bank.jsonStr"
+                  :key="index"
+                  class="lisSty"
+                >
+                  <text
+                    :class="{
+                      right:
+                        item.optionsId == bank.ques ||
+                        item.optionsId == bank.ans,
+                      wrong:
+                        item.optionsId == bank.ques && bank.ques != bank.ans,
+                    }"
+                    class="activeTI"
+                    >{{ ast[index] }}</text
+                  >
+                  <view class="flex_auto">
+                    {{ item.content }}
+                    <view v-if="item.imgUrl">
+                      <image
+                        style="width: 600rpx"
+                        mode="widthFix"
+                        :src="$method.splitImgHost(item.imgUrl)"
+                      ></image>
+                    </view>
+                  </view>
+                </view>
+              </view>
+            </view>
+            <view>
+              <view class="pad_8 answer">
+                <view>正确答案:{{ ast[bank.ans - 1] }}</view>
+                <view>我的答案:{{ ast[bank.ques - 1] || "" }}</view>
+              </view>
+              <view class="pad_8 answerInfos">
+                <view class="answerTitle">答案解析</view>
+                <view class="answerContent">
+                  <rich-text :nodes="bank.analysisContent"></rich-text>
+                </view>
+              </view>
+            </view>
+          </template>
+
+          <template v-if="bank.type == 2">
+            <view class="pad_8 titBox no-margin">
+              <view v-if="!bank.ques">
+                <view
+                  v-for="(item, index) in bank.jsonStr"
+                  :key="index"
+                  class="lisSty"
+                >
+                  <view :class="{ checked: item.checked }" class="activeTI">{{
+                    ast[index]
+                  }}</view>
+                  <view class="flex_auto">
+                    {{ item.content }}
+                    <view v-if="item.imgUrl">
+                      <image
+                        style="width: 600rpx"
+                        mode="widthFix"
+                        :src="$method.splitImgHost(item.imgUrl)"
+                      ></image>
+                    </view>
+                  </view>
+                </view>
+              </view>
+              <view v-if="bank.ques">
+                <view
+                  v-for="(item, index) in bank.jsonStr"
+                  :key="index"
+                  class="lisSty"
+                >
+                  <text
+                    :class="{
+                      right:
+                        (bank.ques &&
+                          bank.ques.indexOf(item.optionsId) != -1) ||
+                        (bank.ans && bank.ans.indexOf(item.optionsId) != -1),
+                      wrong:
+                        bank.ques &&
+                        bank.ques.indexOf(item.optionsId) != -1 &&
+                        bank.ans &&
+                        bank.ans.indexOf(item.optionsId) == -1,
+                    }"
+                    class="activeTI"
+                    >{{ ast[index] }}</text
+                  >
+                  <view class="flex_auto">
+                    {{ item.content }}
+                    <view v-if="item.imgUrl">
+                      <image
+                        style="width: 600rpx"
+                        mode="widthFix"
+                        :src="$method.splitImgHost(item.imgUrl)"
+                      ></image>
+                    </view>
+                  </view>
+                </view>
+              </view>
+            </view>
+            <view>
+              <view class="pad_8 answer">
+                <view
+                  >正确答案:
+                  <text
+                    :key="ansItemIndex"
+                    v-for="(ansItem, ansItemIndex) in bank.ans"
+                    >{{ ast[ansItem - 1] }}</text
+                  >
+                </view>
+                <view
+                  >我的答案:
+                  <text
+                    :key="quesItemIndex"
+                    v-for="(quesItem, quesItemIndex) in bank.ques"
+                    >{{ ast[quesItem - 1] }}</text
+                  >
+                </view>
+              </view>
+              <view class="pad_8 answerInfos">
+                <view class="answerTitle">答案解析</view>
+                <view class="answerContent">
+                  <rich-text :nodes="bank.analysisContent"></rich-text>
+                </view>
+              </view>
+            </view>
+          </template>
+
+          <template v-if="bank.type == 3">
+            <view class="pad_8 titBox no-margin">
+              <view v-if="!bank.ques">
+                <view
+                  v-for="(item, index) in judge"
+                  :key="index"
+                  class="lisSty"
+                >
+                  <view class="activeTI">{{ ast[index] }}</view>
+                  <view class="flex_auto">
+                    {{ item }}
+                    <view v-if="item.imgUrl">
+                      <image
+                        style="width: 600rpx"
+                        mode="widthFix"
+                        :src="$method.splitImgHost(item.imgUrl)"
+                      ></image>
+                    </view>
+                  </view>
+                </view>
+              </view>
+              <view v-if="bank.ques">
+                <view
+                  v-for="(item, index) in judge"
+                  :key="index"
+                  class="lisSty"
+                >
+                  <text
+                    :class="{
+                      right: index == bank.ques || index == bank.ans,
+                      wrong: index == bank.ques && bank.ques != bank.ans,
+                    }"
+                    class="activeTI"
+                    >{{ ast[index] }}</text
+                  >
+                  <view class="flex_auto">
+                    {{ item }}
+                    <view v-if="item.imgUrl">
+                      <image
+                        style="width: 600rpx"
+                        mode="widthFix"
+                        :src="$method.splitImgHost(item.imgUrl)"
+                      ></image>
+                    </view>
+                  </view>
+                </view>
+              </view>
+            </view>
+            <view>
+              <view class="pad_8 answer">
+                <view>正确答案:{{ ast[bank.ans] }}</view>
+                <view>我的答案:{{ ast[bank.ques] || "" }}</view>
+              </view>
+              <view class="pad_8 answerInfos">
+                <view class="answerTitle">答案解析</view>
+                <view class="answerContent">
+                  <rich-text :nodes="bank.analysisContent"></rich-text>
+                </view>
+              </view>
+            </view>
+          </template>
+
+          <!-- 简答题 -->
+          <template v-if="bank.type == 5">
+            <view class="pad_8 titBox">
+              <view class="ans">
+                <view class="ans_submit answerInfos">
+                  <view class="answerTitle">我的答案:</view>
+                  {{ bank.ques.text || "" }}
+                  <view class="imgs">
+                    <image
+                      class="img"
+                      v-for="(ques, quesIndex) in bank.ques.imageList"
+                      :key="quesIndex"
+                      :src="$method.splitImgHost(ques, true)"
+                    ></image>
+                  </view>
+                </view>
+              </view>
+            </view>
+            <view>
+              <view class="pad_8 answerInfos">
+                <view class="answerTitle">答案解析:</view>
+                <view class="answerContent">
+                  <rich-text :nodes="bank.analysisContent"></rich-text>
+                </view>
+              </view>
+            </view>
+          </template>
+
+          <!-- 案例题 -->
+          <template v-if="bank.type == 4">
+            <view class="tabs">
+              <view
+                class="tab"
+                :class="{ current: tabIndex == bank.current }"
+                :key="tabIndex"
+                v-for="(tab, tabIndex) in bank.jsonStr"
+                @click="tabSelect(tabIndex, bankIndex)"
+                >问题{{ tabIndex + 1 }}</view
+              >
+            </view>
+            <view
+              v-for="(ansItem, ansIndex) in bank.jsonStr"
+              v-if="bank.current == ansIndex"
+              :key="ansIndex"
+            >
+              <template v-if="ansItem.type == 1">
+                <view class="pad_8 titBox">
+                  <view class="leftLetters">
+                    <view class="btnType">
+                      <text>单选</text>
+                    </view>
+                  </view>
+                  <view class="titles">
+                    <rich-text :nodes="ansItem.content"></rich-text>
+                  </view>
+                  <view v-if="!bank.ques[ansIndex]">
+                    <view
+                      v-for="(option, childIndex) in ansItem.optionsList"
+                      :key="childIndex"
+                      class="lisSty"
+                    >
+                      <view class="activeTI">{{ ast[childIndex] }}</view>
+                      <view class="flex_auto">
+                        <rich-text
+                          class="textChild"
+                          :nodes="option.content"
+                        ></rich-text>
+                        <view v-if="option.imgUrl">
+                          <image
+                            style="width: 600rpx"
+                            mode="widthFix"
+                            :src="$method.splitImgHost(option.imgUrl)"
+                          ></image>
+                        </view>
+                      </view>
+                    </view>
+                  </view>
+                  <view v-if="bank.ques[ansIndex]">
+                    <view
+                      v-for="(option, childIndex) in ansItem.optionsList"
+                      :key="childIndex"
+                      class="lisSty"
+                    >
+                      <text
+                        :class="{
+                          right:
+                            option.optionsId == bank.ques[ansIndex] ||
+                            option.optionsId == bank.ans[ansIndex],
+                          wrong:
+                            option.optionsId == bank.ques[ansIndex] &&
+                            bank.ques[ansIndex] != bank.ans[ansIndex],
+                        }"
+                        class="activeTI"
+                        >{{ ast[childIndex] }}</text
+                      >
+                      <view class="flex_auto">
+                        <rich-text :nodes="option.content"></rich-text>
+                        <view v-if="option.imgUrl">
+                          <image
+                            style="width: 600rpx"
+                            mode="widthFix"
+                            :src="$method.splitImgHost(option.imgUrl)"
+                          ></image>
+                        </view>
+                      </view>
+                    </view>
+                  </view>
+                </view>
+                <view class="pad_8 answer">
+                  <view>正确答案:{{ ast[bank.ans[ansIndex] - 1] }}</view>
+                  <view
+                    >我的答案:{{ ast[bank.ques[ansIndex] - 1] || "" }}</view
+                  >
+                </view>
+                <view class="pad_8 answerInfos">
+                  <view class="answerTitle">答案解析</view>
+                  <view class="answerContent">
+                    <rich-text :nodes="option.analysisContent"></rich-text>
+                  </view>
+                </view>
+              </template>
+
+              <template v-if="ansItem.type == 2">
+                <view class="pad_8 titBox">
+                  <view class="leftLetters">
+                    <view class="btnType">
+                      <text>多选</text>
+                    </view>
+                  </view>
+                  <view class="titles">
+                    <rich-text :nodes="ansItem.content"></rich-text>
+                  </view>
+                  <view v-if="!bank.ques[ansIndex]">
+                    <view
+                      v-for="(option, childindex) in ansItem.optionsList"
+                      :key="childindex"
+                      class="lisSty"
+                    >
+                      <view
+                        :class="{ checked: option.checked }"
+                        class="activeTI"
+                        >{{ ast[childindex] }}</view
+                      >
+                      <view class="flex_auto">
+                        <rich-text :nodes="option.content"></rich-text>
+                        <view v-if="option.imgUrl">
+                          <image
+                            style="width: 600rpx"
+                            mode="widthFix"
+                            :src="$method.splitImgHost(option.imgUrl)"
+                          ></image>
+                        </view>
+                      </view>
+                    </view>
+                  </view>
+                  <view v-if="bank.ques && bank.ques[ansIndex]">
+                    <view
+                      v-for="(option, childindex) in ansItem.optionsList"
+                      :key="childindex"
+                      class="lisSty"
+                    >
+                      <text
+                        :class="{
+                          right: right(bankIndex, ansIndex, option),
+                          wrong: wrong(bankIndex, ansIndex, option),
+                        }"
+                        class="activeTI"
+                        >{{ ast[childindex] }}</text
+                      >
+                      <view class="flex_auto">
+                        <rich-text :nodes="option.content"></rich-text>
+                        <view v-if="option.imgUrl">
+                          <image
+                            style="width: 600rpx"
+                            mode="widthFix"
+                            :src="$method.splitImgHost(option.imgUrl)"
+                          ></image>
+                        </view>
+                      </view>
+                    </view>
+                  </view>
+                </view>
+                <view>
+                  <view class="pad_8 answer">
+                    <view
+                      >正确答案:
+                      <text
+                        :key="ansItemIndex1"
+                        v-for="(ansItem1, ansItemIndex1) in bank.ans[ansIndex]"
+                        >{{ ast[ansItem1 - 1] }}</text
+                      >
+                    </view>
+                    <view
+                      >我的答案:
+                      <text
+                        :key="quesItemIndex"
+                        v-for="(quesItem, quesItemIndex) in bank.ques[ansIndex]"
+                        >{{ ast[quesItem - 1] }}</text
+                      >
+                    </view>
+                  </view>
+                  <view class="pad_8 answerInfos">
+                    <view class="answerTitle">答案解析</view>
+                    <view class="answerContent">
+                      <rich-text :nodes="ansItem.analysisContent"></rich-text>
+                    </view>
+                  </view>
+                </view>
+              </template>
+
+              <template v-if="ansItem.type == 3">
+                <view class="pad_8 titBox">
+                  <view class="leftLetters">
+                    <view class="btnType">
+                      <text>判断</text>
+                    </view>
+                  </view>
+                  <view class="titles">
+                    <rich-text :nodes="ansItem.content"></rich-text>
+                  </view>
+                  <view v-if="!bank.ques[ansIndex]">
+                    <view
+                      v-for="(option, childindex) in judge"
+                      :key="childindex"
+                      class="lisSty"
+                    >
+                      <view class="activeTI">{{ ast[childindex] }}</view>
+                      <view class="flex_auto">
+                        {{ option }}
+                        <view v-if="option.imgUrl">
+                          <image
+                            style="width: 600rpx"
+                            mode="widthFix"
+                            :src="$method.splitImgHost(option.imgUrl)"
+                          ></image>
+                        </view>
+                      </view>
+                    </view>
+                  </view>
+                  <view v-if="bank.ques[ansIndex]">
+                    <view
+                      v-for="(option, childindex) in judge"
+                      :key="childindex"
+                      class="lisSty"
+                    >
+                      <text
+                        :class="{
+                          right:
+                            childindex == bank.ques[ansIndex] ||
+                            childindex == bank.ans[ansIndex],
+                          wrong:
+                            childindex == bank.ques[ansIndex] &&
+                            bank.ques[ansIndex] != bank.ans[ansIndex],
+                        }"
+                        class="activeTI"
+                        >{{ ast[childindex] }}</text
+                      >
+                      <view class="flex_auto">
+                        {{ option }}
+                        <view v-if="option.imgUrl">
+                          <image
+                            style="width: 600rpx"
+                            mode="widthFix"
+                            :src="$method.splitImgHost(option.imgUrl)"
+                          ></image>
+                        </view>
+                      </view>
+                    </view>
+                  </view>
+                </view>
+                <view>
+                  <view class="pad_8 answer">
+                    <view>正确答案:{{ ast[bank.ans[ansIndex]] }}</view>
+                    <view>我的答案:{{ ast[bank.ques[ansIndex]] || "" }}</view>
+                  </view>
+                  <view class="pad_8 answerInfos">
+                    <view class="answerTitle">答案解析</view>
+                    <view class="answerContent">
+                      <rich-text :nodes="ansItem.analysisContent"></rich-text>
+                    </view>
+                  </view>
+                </view>
+              </template>
+
+              <!-- 简答题 -->
+              <template v-if="ansItem.type == 5">
+                <view class="pad_8 titBox_title">
+                  <view class="leftLetters">
+                    <view class="btnType">
+                      <text>简答</text>
+                    </view>
+                  </view>
+                  <view class="titles">
+                    <rich-text :nodes="ansItem.content"></rich-text>
+                  </view>
+                </view>
+                <view class="pad_8 titBox_title">
+                  <view class="ans">
+                    <view class="ans_submit answerInfos">
+                      <view class="answerTitle">我的答案</view>
+                      {{ bank.ques[ansIndex].text || "" }}
+                      <view
+                        class="imgs"
+                        v-if="
+                          bank.ques[ansIndex] &&
+                          bank.ques[ansIndex].imageList.length
+                        "
+                      >
+                        <image
+                          class="img"
+                          :key="quesIndex"
+                          v-for="(ques, quesIndex) in bank.ques[ansIndex]
+                            .imageList"
+                          :src="$method.splitImgHost(ques, true)"
+                        ></image>
+                      </view>
+                    </view>
+                  </view>
+                </view>
+                <view>
+                  <view class="pad_8 answerInfos">
+                    <view class="answerTitle">答案解析</view>
+                    <view class="answerContent">
+                      <rich-text :nodes="ansItem.analysisContent"></rich-text>
+                    </view>
+                  </view>
+                </view>
+              </template>
+            </view>
+          </template>
+
+          <view class="footer_btn">
+            <view
+              class="collect"
+              @click="collect(collectList[bankIndex], bankIndex)"
+            >
+              <view>
+                <image src="/static/icon/collect.png" mode=""></image>
+                <view>收藏</view>
+              </view>
+            </view>
+            <view class="flex_center" @click="openFooterTab">
+              <view class="up-icon">
+                <image src="/static/up.png"></image>
+              </view>
+              答题卡
+            </view>
+            <view class="collect" @click="pdsubmit">
+              <view>
+                <image src="/static/jj.png" mode=""></image>
+                <view>交卷</view>
+              </view>
+            </view>
+          </view>
+        </view>
+      </swiper-item>
+    </swiper>
+
+    <u-popup v-model="show" mode="bottom" border-radius="14" height="680rpx">
+      <view class="popupView">
+        <view class="popupTops">
+          <view class="topIcon"></view>
+          点击编号即可跳转至对应题目
+        </view>
+        <view class="popupContent">
+          <scroll-view scroll-y="true" style="height: 506rpx">
+            <view class="boxSty">
+              <view
+                v-for="(item, index) in questionList"
+                :key="index"
+                @click="changeIndex(index)"
+                :class="{
+                  isRight: isRight(item, index),
+                  isWrong: isWrong(item, index),
+                  isPart: isPart(item, index),
+                }"
+                class="liListSty"
+                >{{ index + 1 }}</view
+              >
+            </view>
+          </scroll-view>
+        </view>
+      </view>
+    </u-popup>
+
+    <view class="dialog" v-if="showDialog">
+      <view class="text">左右滑动切换上下题</view>
+      <view class="btn" @click="hideDialog">我知道了</view>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      id: "",
+      current: 0,
+      questionList: [],
+      ast: ["A", "B", "C", "D", "E", "F", "G"],
+      judge: ["错误", "正确"],
+      show: false,
+      showDialog: false,
+      bankList: [],
+      recordId: "",
+    };
+  },
+  onLoad(option) {
+    this.id = option.id || "";
+    this.recordId = option.recordId || "";
+
+    let showDialog = uni.getStorageSync("showDialog");
+
+    if (showDialog) {
+      this.showDialog = false;
+    } else {
+      this.showDialog = true;
+      uni.setStorageSync("showDialog", "1");
+    }
+    this.goodsQuestionList();
+  },
+  onUnload() {},
+  methods: {
+    /**
+     * 是否有上传图片
+     */
+    hasImgs(bank) {
+      return bank.ansText.imageList.length == 0;
+    },
+
+    goodsQuestionList() {
+      this.$api.mockReport(this.recordId).then((res) => {
+        let questionList = JSON.parse(res.data.data.historyExamJson);
+
+        questionList.forEach((json) => {
+          //只获取类型1,2,3 单选,多选,判断 ,主观题灭有对错
+          if (json.type == 1 || json.type == 3) {
+            //单选判断
+            if (json.ans != json.ques) {
+              this.questionList.push(json);
+            }
+          } else if (json.type == 2) {
+            //判断是否全对
+            let isRight = json.ans.every((quesItem, quesIndex) => {
+              if (json.ques) {
+                return json.ques[quesIndex] == json.ans[quesIndex];
+              } else {
+                return false;
+              }
+            });
+
+            if (!isRight) {
+              this.questionList.push(json);
+            }
+          }
+        });
+      });
+    },
+
+    openFooterTab() {
+      this.show = true;
+    },
+    hideDialog() {
+      this.showDialog = false;
+    },
+    changeIndex(index) {
+      this.current = index;
+    },
+
+    swiperChange(e) {
+      this.current = e.detail.current;
+    },
+
+    isRight(item, index) {
+      //单选
+      if (this.questionList[index].ques) {
+        if (item.type == 1) {
+          return this.questionList[index].ques == this.questionList[index].ans;
+          //多选
+        } else if (item.type == 2) {
+          //每一项都相等
+          return this.questionList[index].ans.every((item, i) => {
+            return item == this.questionList[index].ques[i];
+          });
+          //判断
+        } else if (item.type == 3) {
+          return this.questionList[index].ques == this.questionList[index].ans;
+        } else {
+          return false;
+        }
+      } else {
+        return false;
+      }
+    },
+
+    right(bankIndex, ansIndex, option) {
+      if (
+        this.questionList[bankIndex].ques[ansIndex] &&
+        this.questionList[bankIndex].ans[ansIndex]
+      ) {
+        if (
+          this.questionList[bankIndex].ques[ansIndex].indexOf(
+            option.optionsId
+          ) != -1 ||
+          this.questionList[bankIndex].ans[ansIndex].indexOf(
+            option.optionsId
+          ) != -1
+        ) {
+          return true;
+        } else {
+          return false;
+        }
+      } else {
+        return false;
+      }
+    },
+
+    wrong(bankIndex, ansIndex, option) {
+      if (
+        this.questionList[bankIndex].ques[ansIndex] &&
+        this.questionList[bankIndex].ans[ansIndex]
+      ) {
+        if (
+          this.questionList[bankIndex].ques[ansIndex].indexOf(
+            option.optionsId
+          ) != -1 &&
+          this.questionList[bankIndex].ans[ansIndex].indexOf(
+            option.optionsId
+          ) == -1
+        ) {
+          return true;
+        } else {
+          return false;
+        }
+      } else {
+        return false;
+      }
+    },
+
+    isWrong(item, index) {
+      if (this.questionList[index].ques) {
+        //单选
+        if (item.type == 1) {
+          return this.questionList[index].ques != this.questionList[index].ans;
+          //多选
+        } else if (item.type == 2) {
+          //每一项都相等
+          return this.questionList[index].ques.some((item, i) => {
+            return this.questionList[index].ans.indexOf(item) == -1;
+          });
+          //判断
+        } else if (item.type == 3) {
+          return this.questionList[index].ques != this.questionList[index].ans;
+        } else {
+          return false;
+        }
+      } else {
+        return false;
+      }
+    },
+    isPart(item, index) {
+      if (this.questionList[index].ques) {
+        if (item.type == 2) {
+          let isWrong = this.questionList[index].ques.some((item, i) => {
+            return this.questionList[index].ans.indexOf(item) == -1;
+          });
+
+          let isRight = this.questionList[index].ans.every((item, i) => {
+            return item == this.questionList[index].ques[i];
+          });
+
+          if (!isRight && !isWrong) {
+            return true;
+          }
+        }
+      } else {
+        return false;
+      }
+    },
+
+    tabSelect(index, bankindex) {
+      this.$set(this.questionList[bankindex], "current", index);
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.questionBank {
+  width: 100%;
+  height: 100vh;
+  display: flex;
+  flex-direction: column;
+}
+.swiper {
+  width: 100%;
+  flex: 1;
+}
+.lisSty {
+  margin-bottom: 16rpx;
+  display: flex;
+
+  .flex_auto {
+    flex: 1;
+  }
+}
+.activeTI {
+  vertical-align: middle;
+  display: inline-block;
+  border: 1rpx solid #eee;
+  border-radius: 50rpx;
+  height: 48rpx;
+  line-height: 46rpx;
+  text-align: center;
+  width: 48rpx;
+  margin-right: 15rpx;
+  color: #666;
+  font-size: 30rpx;
+
+  &.right {
+    color: #fff;
+    background: #36c75a;
+  }
+
+  &.wrong {
+    color: #fff;
+    background: #ff3b30;
+  }
+
+  &.checked {
+    color: #fff;
+    background: #007aff;
+  }
+}
+
+.submit_checkbox {
+  position: fixed;
+  left: 0;
+  right: 0;
+  bottom: 120rpx;
+  margin: 20rpx auto;
+  width: 526rpx;
+  height: 80rpx;
+  background: rgba(0, 122, 255, 1);
+  color: #fff;
+  text-align: center;
+  line-height: 80rpx;
+  font-size: 30rpx;
+  border-radius: 40rpx;
+}
+.titles {
+  overflow: hidden;
+  margin-bottom: 24rpx;
+}
+.titBox {
+  padding: 41rpx 25rpx 24rpx 25rpx;
+}
+
+.titBox_title {
+  padding: 21rpx;
+}
+
+.tabs {
+  margin: 10rpx;
+  display: flex;
+  .tab {
+    margin: 0 4rpx;
+    padding: 10rpx 13rpx;
+    text-align: center;
+    color: #007aff;
+    font-size: 28rpx;
+    border-radius: 16rpx;
+    background: #fff;
+
+    &.current {
+      color: #fff;
+      background: #007aff;
+    }
+  }
+}
+
+.ans {
+  margin: 8rpx 8rpx 8rpx;
+
+  .ans_input {
+    border-radius: 16rpx;
+    background: #fff;
+    .top {
+      border-bottom: 1rpx solid #eeeeee;
+      padding: 16rpx;
+      display: flex;
+      align-items: center;
+
+      .icon {
+        margin-right: 20rpx;
+        width: 40rpx;
+        height: 38rpx;
+      }
+
+      .progress {
+        flex: 1;
+      }
+
+      .submit {
+        width: 168rpx;
+        height: 48rpx;
+        line-height: 48rpx;
+        text-align: center;
+        color: #fff;
+        font-size: 30rpx;
+        background: #007aff;
+        border-radius: 24rpx;
+
+        &.disabled {
+          opacity: 0.6;
+        }
+      }
+    }
+
+    .textarea {
+      textarea {
+        width: 100%;
+        height: 287rpx;
+        padding: 10rpx;
+      }
+    }
+
+    .imgs {
+      overflow: hidden;
+      display: flex;
+      width: 100%;
+      .img {
+        width: 104rpx;
+        height: 104rpx;
+        border-radius: 8rpx;
+        position: relative;
+        margin: 20rpx;
+
+        text {
+          position: absolute;
+          right: -15rpx;
+          top: -15rpx;
+          width: 30rpx;
+          height: 30rpx;
+          text-align: center;
+          line-height: 30rpx;
+          color: #fff;
+          background: #ff3b30;
+          border-radius: 50%;
+        }
+
+        image {
+          width: 100%;
+          height: 100%;
+        }
+      }
+    }
+  }
+
+  .ans_submit {
+    padding: 16rpx;
+    border-radius: 16rpx;
+    background: #fff;
+
+    .imgs {
+      overflow: hidden;
+      display: flex;
+      width: 100%;
+      .img {
+        width: 104rpx;
+        height: 104rpx;
+        border-radius: 8rpx;
+        position: relative;
+        margin: 20rpx;
+
+        image {
+          width: 100%;
+          height: 100%;
+        }
+      }
+    }
+  }
+}
+.leftLetters {
+  display: flex;
+  align-items: center;
+  width: 220rpx;
+  .btnType {
+    padding: 5rpx 10rpx;
+    border: 1rpx solid #007aff;
+    border-radius: 10rpx;
+    background-color: rgba(0, 122, 255, 0.1);
+    font-size: 28rpx;
+    color: #007aff;
+    margin-right: 15rpx;
+  }
+}
+.firstLetter {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 30rpx;
+}
+.popupView {
+  height: 100%;
+  padding-bottom: 100rpx;
+  .popupTops {
+    height: 77rpx;
+    border-bottom: 1rpx solid #eee;
+    text-align: center;
+    line-height: 77rpx;
+    font-size: 24rpx;
+    color: #999;
+    position: relative;
+    .topIcon {
+      position: absolute;
+      top: 10rpx;
+      left: 50%;
+      transform: translateX(-50%);
+      width: 80rpx;
+      height: 8rpx;
+      background-color: #999;
+      border-radius: 4rpx;
+    }
+  }
+  .popupContent {
+  }
+}
+.pageContent {
+  position: relative;
+  background-color: #eaeef1;
+  height: 100%;
+  overflow-y: scroll;
+  padding-top: 8rpx;
+  padding-bottom: 100rpx;
+}
+.pad_8 {
+  background-color: #fff;
+  margin: 0rpx 8rpx 8rpx;
+  border-radius: 16rpx;
+
+  &.no-margin {
+    margin-top: -16rpx;
+    border-radius: 0 0 16rpx 16rpx;
+  }
+}
+.answer {
+  height: 80rpx;
+  line-height: 80rpx;
+  padding: 0rpx 24rpx;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  color: #666;
+  font-size: 30rpx;
+}
+.footer_btn {
+  background-color: #fff;
+  z-index: 10078;
+  position: fixed;
+  bottom: 0rpx;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  width: 100%;
+  height: 98rpx;
+  padding: 0rpx 38rpx;
+  border-top: 1rpx solid #eee;
+
+  .flex_center {
+    flex: 1;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    flex-direction: column;
+    margin: 0 200rpx;
+    font-size: 24rpx;
+    color: #999999;
+
+    .up-icon {
+      margin-bottom: 18rpx;
+      width: 100%;
+      display: flex;
+      justify-content: center;
+      image {
+        width: 58rpx;
+        height: 21rpx;
+      }
+    }
+  }
+
+  .collect {
+    visibility: hidden;
+    width: 100rpx;
+
+    &.show {
+      visibility: visible;
+    }
+
+    > view {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+
+      image {
+        width: 32rpx;
+        height: 32rpx;
+        margin-bottom: 6rpx;
+      }
+
+      view {
+        font-size: 24rpx;
+        color: #999999;
+      }
+    }
+  }
+}
+.boxSty {
+  padding: 44rpx 41rpx 0rpx;
+}
+.liListSty {
+  border: 1rpx solid #eeeeee;
+  width: 88rpx;
+  height: 88rpx;
+  border-radius: 32rpx;
+  text-align: center;
+  line-height: 88rpx;
+  color: #333;
+  font-size: 32rpx;
+  float: left;
+  margin: 20rpx 23rpx;
+
+  &.isRight {
+    border: 1rpx solid #eeeeee;
+    color: #fff;
+    background: #36c75a;
+  }
+
+  &.isWrong {
+    border: 1rpx solid #eeeeee;
+    color: #fff;
+    background: #ff3b30;
+  }
+
+  &.isPart {
+    border: 1rpx solid #eeeeee;
+    color: #fff;
+    background: #FFC53D;
+  }
+}
+.answerInfos {
+  padding: 25rpx 25rpx 25rpx 23rpx;
+}
+.answerTitle {
+  margin-bottom: 28rpx;
+  color: #666;
+  font-size: 30rpx;
+}
+.answerContent {
+  font-size: 30rpx;
+  color: #666;
+}
+
+.textChild {
+  display: inline-block;
+  vertical-align: middle;
+}
+
+.dialog {
+  position: fixed;
+  left: 0;
+  top: 0;
+  width: 100%;
+  height: 100%;
+  background-color: rgba(0, 0, 0, 0.8);
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  z-index: 20000;
+
+  .pointer {
+    width: 338rpx;
+    height: 240rpx;
+  }
+
+  .text {
+    font-size: 32rpx;
+    color: #ffffff;
+    text-align: center;
+  }
+
+  .btn {
+    width: 242rpx;
+    height: 82rpx;
+    border: 2rpx solid #ffffff;
+    border-radius: 16rpx;
+    text-align: center;
+    line-height: 82rpx;
+    margin: 41rpx auto;
+    color: #fff;
+    font-size: 32rpx;
+  }
+}
+.popboxs {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+}
+.classTops {
+  flex-shrink: 0;
+  padding: 39rpx 0rpx 4rpx;
+  font-weight: bold;
+  color: #333;
+  font-size: 30rpx;
+}
+.textStys {
+  width: 100%;
+  flex: 1;
+  padding: 36rpx;
+}
+.classFootsty {
+  flex-shrink: 0;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  padding: 10rpx 0rpx 40rpx;
+  .btnsty {
+    width: 200rpx;
+    height: 80rpx;
+    border-radius: 40rpx;
+    font-weight: bold;
+    font-size: 30rpx;
+    text-align: center;
+    line-height: 80rpx;
+  }
+  .btns1 {
+    background-color: #f5f5f5;
+    color: #007aff;
+  }
+  .btns2 {
+    margin-left: 40rpx;
+    background-color: #007aff;
+    color: #ffffff;
+  }
+}
+</style>

+ 192 - 0
pages5/liveDetail/course.vue

@@ -0,0 +1,192 @@
+<template>
+  <view style="padding: 30rpx">
+    <nav-bar title="所有课程"></nav-bar>
+    <view v-if="!courseList.length">
+      <u-empty text="暂无课程" mode="list"></u-empty>
+    </view>
+    <view
+      v-else
+      @click="jump(item, index)"
+      v-for="(item, index) in courseList"
+      :key="index"
+      style="margin-bottom: 30rpx"
+    >
+      <view class="class_item">
+        <image
+          :src="$method.splitImgHost(item.coverUrl, true)"
+          style="height: 316rpx; width: 100%; border-radius: 24rpx"
+        ></image>
+        <view style="color: #333333; font-weight: bold; font-size: 32rpx">{{
+          item.courseName
+        }}</view>
+      </view>
+      <view class="bottomBox">
+        <!-- <view class=".content_box">
+          <image src="/static/icon/wk_icon3.png" class="wk_icon"></image>
+          学习进度:{{ item.stuAllNum + item.recordNum }}/{{
+            item.secAllNum + item.examNum
+          }}
+        </view> -->
+        <view class="box_progress">
+          <view style="width: 60%">
+						<!-- <u-line-progress
+              height="22"
+              :show-percent="false"
+              active-color="#ff9900"
+              :percent="((item.stuAllNum + item.recordNum) / (item.secAllNum + item.examNum)) * 100"
+            ></u-line-progress> -->
+					</view>
+          <view
+            ><u-button
+              type="warning"
+              size="mini"
+              @click.stop="jump(item, index)"
+              >进入学习</u-button
+            ></view
+          >
+        </view>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      goodsId: 0,
+      gradeId: 0,
+      courseList: [],
+      orderGoodsId: 0,
+      param: {
+        pageNum: 1,
+        pageSize: 10,
+        total: 0,
+      },
+      businessData: {},
+      itemIndex: "",
+    };
+  },
+  onLoad(option) {
+    this.goodsId = Number(option.goodsId);
+    this.gradeId = Number(option.goodsId);
+    this.orderGoodsId = Number(option.orderGoodsId);
+    // uni.setStorageSync('courseGoodsId', this.goodsId);
+    this.courseCourseList();
+    this.$store.getters.dictObj;
+  },
+  onShow() {
+    if (this.itemIndex !== "") {
+      this.refreshByIndex();
+    }
+  },
+  onReachBottom() {
+    if (this.courseList.length < this.param.total) {
+      this.param.pageNum++;
+      this.courseCourseList();
+    }
+  },
+  methods: {
+    /**
+     * 返回刷新之前进入的课程数据
+     */
+    refreshByIndex() {
+      this.$api
+        .courseCourseList({
+          pageNum: this.itemIndex + 1,
+          pageSize: 1,
+          goodsId: this.goodsId,
+          gradeId: 0,
+        })
+        .then((res) => {
+          if (res.data.code == 200) {
+            this.$set(this.courseList, this.itemIndex, res.data.rows[0]);
+          }
+        });
+    },
+    /**
+     * 获取业务层次详情
+     */
+    courseBusiness(businessId) {
+      this.$api.courseBusiness(businessId).then((res) => {
+        this.businessData = res.data.data;
+      });
+    },
+    jump(item, index) {
+      this.itemIndex = index;
+
+      this.$navTo.togo("/pages3/live/detail", {
+        courseId: item.courseId,
+        goodsId: this.goodsId,
+				gradeId:0,
+        orderGoodsId: this.orderGoodsId,
+      });
+    },
+    courseCourseList() {
+      let self = this;
+      this.param.goodsId = this.goodsId;
+      this.param.gradeId = this.gradeId;
+      this.$api.courseCourseList(this.param).then((res) => {
+        if (res.data.code == 200) {
+          self.courseList.push.apply(self.courseList, res.data.rows);
+          self.param.total = res.data.total;
+					console.log(res.data.rows.length,'res.data.rows.length')
+          // if (res.data.rows.length) {
+          //   this.courseBusiness(res.data.rows[0].businessId);
+          // }
+        }
+      });
+    },
+    appointment() {
+      this.$navTo.togo("/pages2/appointment/index?orderGoodsId="+this.orderGoodsId);
+    },
+  },
+};
+</script>
+<style>
+page {
+  background: #eaeef1;
+}
+</style>
+<style scope lang="scss">
+
+.box_progress {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-top: 20rpx;
+}
+.bottomBox {
+  background: #ffffff;
+  width: 94%;
+  border-bottom-left-radius: 24rpx;
+  border-bottom-right-radius: 24rpx;
+  margin: 0 auto;
+  padding: 20rpx;
+}
+.content_box {
+  display: flex;
+  align-items: center;
+  color: #999999;
+  margin-top: 8rpx;
+}
+.content {
+  color: #000000;
+  margin: 0 8rpx;
+}
+.wk_icon {
+  width: 24rpx;
+  height: 24rpx;
+  margin-right: 8rpx;
+}
+
+.class_item {
+  width: 100%;
+  background: #ffffff;
+  box-shadow: 0rpx 10rpx 9rpx 1rpx rgba(165, 196, 239, 0.1);
+  border-radius: 24rpx;
+  padding: 20rpx;
+  z-index: 999;
+  position: relative;
+}
+</style>

+ 549 - 0
pages5/liveDetail/index.vue

@@ -0,0 +1,549 @@
+<template>
+	<view>
+		<nav-bar title="课程详情"></nav-bar>
+		<view class="videoBox" >
+			<view >
+				<view class="video_box" v-if="!startStatus">
+					<image :src="$method.splitImgHost(detail.coverUrl)" style="width: 100%;height: 460rpx;"></image>
+					<image v-if="false" class="video_play" src="/static/play.png" @click="startVideo"></image>
+				</view>
+				<view v-else class="video_box" style="width: 100%;height: 460rpx;">
+					<polyv-player
+						id="playerVideo"
+						playerId="playerVideo"
+						height="460rpx"
+						:vid="vid"
+						:showSettingBtn="true"
+						:enablePlayGesture="true"
+						:playbackRate="playbackRate"
+						:isAllowSeek="isAllowSeek"
+						:autoplay="autoplay"
+						:startTime="startTime"
+						@statechange="onStateChange"
+					></polyv-player>
+				</view>
+				<view style="padding:20rpx;">
+					<view style="display: flex;">
+						<view class="yearTag" v-if="detail.year">{{detail.year}}</view>
+						<view class="titleTag">{{detail.goodsName}}</view>
+					</view>
+					<view style="display: flex;justify-content: space-between;margin-top: 13rpx;">
+						<view class="noteTag"><image src="/static/icon/wk_icon1.png" class="wk_icon"></image>
+						共 <text class="blackFont">{{courseList.length}} 课程 {{detail.classHours}}</text> 学时</view>
+						
+					</view>
+				</view>
+			</view>
+			<u-line color="#D6D6DB" />
+			<view style="height: 80rpx;">
+				<view><u-tabs :list="list" :item-width="itemWidth()" font-size="30" bar-width="24"  :current="current" @change="change" active-color="#007AFF"></u-tabs></view>
+			</view>
+			
+		</view>
+		<view style="padding: 20rpx;padding-bottom: 100rpx;position: relative;" v-show="current==0">
+			<view class="content">
+				<view v-html="detail.mobileDetailHtml" style="width: 100%;overflow: hidden;"></view>
+			</view>
+		</view>
+		<view style="padding: 20rpx;padding-bottom: 100rpx;position: relative;" v-show="current==1">
+			<view >
+				<view v-for="(item,index) in courseList" :key="index" >
+					<view class="courseItemBox" >
+						<view class="courseItem" @click="openCourse(item)">
+							<view class="courseName">{{item.courseName}}</view>
+							<view>
+								<image src="/static/icon/up.png" class="icon_up" v-if="item.down"></image>
+								<image src="/static/icon/down.png" class="icon_up" v-if="!item.down"></image>
+							</view>
+						</view>
+						<view v-show="!item.down">
+							<view v-for="(itemM,indexM) in item.menuList"  :key="indexM">
+								<courseModule :courseId="itemM.courseId" :needOpen="(isFirstEnter && menuIndex[0] === index && menuIndex[1] === indexM) ? true : false" v-if="itemM.type==1" :menuItem="itemM"></courseModule>
+								<courseChapter :courseId="itemM.courseId" :needOpen="(isFirstEnter && menuIndex[0] === index && menuIndex[1] === indexM) ? true : false" v-if="itemM.type==2" :isBuy="false" :menuItem="itemM"></courseChapter>
+								<courseSection :courseId="itemM.courseId" v-if="itemM.type==3" :isBuy="false" :menuItem="itemM"></courseSection>
+								<u-line></u-line>
+								
+							</view>
+						</view>
+					</view>
+					
+				</view>
+			</view>
+		</view>
+		<view style="padding: 20rpx;padding-bottom: 100rpx;position: relative;" v-show="current==2">
+			<view >
+				<view v-for="(item,index) in freeMenuList" :key="index" >
+					<view class="courseItemBox" >
+						<view class="courseItem">
+							<view class="courseName">{{item.freeExamName}}</view>
+						</view>
+					</view>
+					
+				</view>
+			</view>
+		</view>
+		<view class="bottomBox" v-if="!hideBuyState">
+			<view class="priceTag">¥ {{toFixed(detail.standPrice)}}</view>
+			<view style="display: flex;color: #FFFFFF;align-items: center;">
+				<view class="btn1" @click="addCart">加购物车</view>
+				<view class="btn2" @click="buy">立即购买 </view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+import courseModule from '@/components/course/courseModule.vue';
+import courseChapter from '@/components/course/courseChapter.vue';
+import courseSection from '@/components/course/courseSection.vue';
+import { mapGetters,mapMutations  } from 'vuex';
+export default {
+	components: {
+		courseModule,
+		courseChapter,
+		courseSection
+	},
+	data() {
+		return {
+			id:0,
+			list: [],
+			menuIndex:[],
+			current:0,
+			detail:{},
+			courseList:[],
+			menuList:[],
+			freeMenuList:[],
+			startStatus:false,
+			playbackRate: [1.0],
+			isAllowSeek:'no',
+			vid:'',
+			autoplay:true,
+			listenConfigList:[],
+			listenSecond:0,
+			isFirstEnter:true, //是否首次进入
+			timer:null,
+			businessData:{},
+			startTime:0
+		};
+	},
+	computed: { ...mapGetters(['userInfo','goodsAuditionConfigIdList','playSectionId','hideBuyState']) },
+	onLoad(option) {
+		this.id = option.id;
+		this.getDetail()
+		this.goodsCourseList()
+		this.appCommonGoodsCourseModuleFreeExamList();
+	},
+	onUnload(option) {
+		this.$store.commit('setPlaySectionId', {playSectionId  :0});
+		//移除所有的事件监听器
+		uni.$off();
+	},
+	mounted() {
+		let self = this
+		uni.$on('getSection', item => {
+			console.log(item)
+			//播放试听
+			self.listenSecond = 0
+			for (var itemChild of self.listenConfigList) {
+				if(self.playSectionId == (itemChild.sectionId || itemChild.menuId) && item.courseId == itemChild.courseId){
+					if(itemChild.auditionMinute>0){
+				//		self.listenSecond = itemChild.auditionMinute *60 //试听秒数
+						self.listenSecond = itemChild.auditionMinute //试听秒数 auditionMinute调整为秒单位
+					}
+				}
+			}
+			if(self.listenSecond>0){
+				if(self.timer){
+					clearInterval(self.timer);
+				}
+				 if(self.vid){
+					 //切换视频
+					 var polyvPlayerContext = self.selectComponent('#playerVideo');
+					 polyvPlayerContext.changeVid(item.recordingUrl)
+				 }else{
+					 self.vid = item.recordingUrl
+				 }
+				
+				self.startStatus = true
+				self.startTime = 0
+			}else{
+				
+				self.$u.toast('试听配置错误');
+			}
+			
+		})
+		this.updateChapterOpen(true)
+	},
+	methods: {
+		 ...mapMutations(['updateChapterOpen']),
+		 itemWidth() {
+			 return (100/this.list.length)+'%'
+		 },
+		appCommonGoodsCourseModuleFreeExamList() {
+		 this.$api.appCommonGoodsCourseModuleFreeExamList(this.id).then(res => {
+			 if(res.data.data.length) {
+				this.freeMenuList = res.data.data;
+				 this.list =  [
+						{
+							name: '详情'
+						},
+						{
+							name: '大纲'
+						},
+						{
+							name: '赠送'
+						}
+					]
+				 } else {
+					 this.list =  [
+							{
+								name: '详情'
+							},
+							{
+								name: '大纲'
+							}
+						]
+				 }
+				 
+				 console.log(this.list)
+		 })
+		},
+		courseBusiness(){
+			this.$api.courseBusiness(this.detail.businessId).then(res => {
+				this.businessData = res.data.data;
+			})
+		},
+		toFixed(number) {
+			if(number > 0) {
+				return number.toFixed(2)
+			} else {
+				return '0.00'
+			}
+		},
+		onStateChange(newstate, oldstate) {
+			if (newstate.detail.newstate == 'playing') {
+				//开始播放
+				if(this.timer){
+					clearInterval(this.timer);
+				}
+				this.timer = setInterval(this.timeEvent, 1500);//定时器
+			}
+			
+		},
+		closePlay(){
+			this.$store.commit('setPlaySectionId', {playSectionId  :0});
+			this.vid = ""
+			this.startStatus = false
+		},
+		timeEvent() {
+			let self = this
+		        var polyvPlayerContext = this.selectComponent('#playerVideo');
+				if (polyvPlayerContext != null) {
+					let PlayCurrentTime = polyvPlayerContext.getCurrentTime();
+					if(PlayCurrentTime>=this.listenSecond){
+						polyvPlayerContext.stop();
+						polyvPlayerContext.exitFullScreen();
+						clearInterval(this.timer);
+						this.timer = null
+						uni.showModal({
+							title: '提示',
+							content: '试听结束,购买课程可学习全部',
+							showCancel:false,
+							success: function(resst) {
+								self.closePlay()
+							}
+						});
+					}
+				}
+		},
+		openCourse(item){
+			item.down = !item.down
+			if(!item.down&&item.menuList.length==0){
+				this.getMenuList(item)
+			}
+			
+		},
+		addShopCart() {
+			let self = this
+			this.$api.addCart({goodsId:this.id}).then(res => {
+				if(res.data.code==200){
+					uni.setStorageSync('updateCart',1) //提醒刷新购物车
+					uni.showToast({
+					    title: '添加成功'
+					});
+				}else{
+					this.$u.toast(res.data.msg);
+				}
+			});
+		},
+		goodsCourseList() {
+			let self = this
+			this.$api.goodsCourseList(this.id).then(res => {
+				if(res.data.code==200){
+					for(let i=0;i<res.data.rows.length;i++){
+						let item = res.data.rows[i]
+						item.down = true
+						item.menuList = []
+					}
+					self.courseList = res.data.rows;
+					this.getFirstCourse();
+				}
+			});
+		},
+		/**
+		 * 获取第一个有模块或者章的课程
+		 */
+		async getFirstCourse() {
+			for(let i = 0; i < this.courseList.length; i++) {
+				
+				let menuIndexOrFalse = await this.getCourseMenus(this.courseList[i]);
+				
+				if(menuIndexOrFalse !== false) {
+					this.menuIndex = [i,menuIndexOrFalse]
+					this.openCourse(this.courseList[i])
+					break
+				}
+			}
+		},
+		getCourseMenus(item) {
+			return new Promise(resolve => {
+				this.$api.menuList({courseId:item.courseId}).then(res => {
+					if(res.data.code==200){
+						for(let i=0;i<res.data.rows.length;i++){
+							if(res.data.rows[i].type == 1 || res.data.rows[i].type == 2) {
+								resolve(i)
+								break;
+							}
+						}
+					}
+				});
+			})
+			
+		},
+		getMenuList(item) {
+			let self = this
+			this.$api.menuList({courseId:item.courseId}).then(res => {
+				if(res.data.code==200){
+					for(let i=0;i<res.data.rows.length;i++){
+						let item = res.data.rows[i]
+						item.down = true
+						item.id = item.menuId
+						item.name = item.menuName
+						
+						if(item.type==3){
+							//判断是否试听
+							item.tryListen = false
+							if(self.goodsAuditionConfigIdList.indexOf(item.id)!==-1){
+								item.tryListen = true
+							}	
+						}
+					}
+					item.menuList = res.data.rows
+				}
+			});
+		},
+		getDetail() {
+			let self = this
+			let sectionIdList = []
+			this.$api.commonGoodsDetail(this.id).then(res => {
+				if(res.data.code==200){
+					if(res.data.data.mobileDetailHtml){
+						res.data.data.mobileDetailHtml = res.data.data.mobileDetailHtml.replace(/<img/gi,'<img style="max-width:100%;"')
+					}
+					
+					
+					self.detail = res.data.data
+					this.courseBusiness();
+					if(self.detail.goodsAuditionConfig){
+						self.listenConfigList = JSON.parse(self.detail.goodsAuditionConfig)
+						for (var itemChild of self.listenConfigList) {
+							sectionIdList.push(itemChild.sectionId)//存储试听节ID
+						}
+						self.$store.commit('setGoodsAuditionConfigIdList', {goodsAuditionConfigIdList:sectionIdList});
+					}
+				}
+			});
+		},
+		buy(){
+			if(this.$method.isGoLogin()){
+				return
+			}
+			this.$navTo.togo('/pages2/order/confirm_list?id='+this.id);
+		},
+		addCart(){
+			if(this.$method.isGoLogin()){
+				return
+			}
+			this.addShopCart()
+		},
+		open(item){
+			item.showChildren = !item.showChildren
+		},
+		change(index){
+			this.current = index;
+		}
+	}
+};
+</script>
+<style >
+	page{
+		background-color: #EAEEF1;
+	}
+</style>
+<style scope>
+	.video_t2 {
+		font-size: 24rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #666666;
+	}
+	.video_t1 {
+		height: 80rpx;
+		color: #333333;
+		line-height: 80rpx;
+		font-size: 30rpx;
+		font-family: PingFang SC;
+		font-weight: bold;
+		color: #333333;
+		overflow: hidden;
+		text-overflow:ellipsis;
+		white-space: nowrap;
+	}
+	.video_t1_t {
+		display: flex;
+		flex-direction: column;
+		height: 80rpx;
+		color: #333333;
+		text-align: center;
+		align-items: center;
+		border-left: solid 1px #d6d6db;
+	}
+	.video_play {
+		position: absolute;
+		width: 95rpx;
+		height: 95rpx;
+		top: 0;
+		left: 0;
+		right: 0;
+		bottom: 0;
+		margin: auto;
+	}
+	.video_box {
+		position: relative;
+	}
+	.courseName{
+		white-space:nowrap;
+		overflow:hidden;
+		text-overflow:ellipsis; 
+	}
+	.videoBox{
+		background-color: #FFFFFF;
+		width: 100%;
+		/* height: 680rpx; */
+		z-index: 999;
+	}
+	.icon_up{
+		width: 32rpx;
+		height: 32rpx;
+	}
+	.contentBox{
+		
+	}
+	.courseItemBox{
+		background: #FFFFFF;
+		border-radius: 16rpx;
+		padding: 0 10rpx;
+		margin-bottom: 20rpx;
+	}
+	.courseItem{
+		height: 80rpx;
+		color: #333333;
+		font-size: 32rpx;
+		line-height: 80rpx;
+		font-weight: bold;
+		display: flex;
+		justify-content: space-between;
+
+	}
+	.content{
+		background-color: #FFFFFF;
+		width: 100%;
+	}
+	.btn2{
+		width: 200rpx;
+		height: 64rpx;
+		background: linear-gradient(0deg, #FFB102, #FD644F);
+		box-shadow: 0rpx 10rpx 16rpx 4rpx rgba(1, 99, 235, 0.04);
+		border-radius: 32rpx;
+		line-height: 64rpx;
+		text-align: center;
+	}
+	.btn1{
+		width: 200rpx;
+		height: 64rpx;
+		background: linear-gradient(0deg, #015EEA, #00C0FA);
+		border-radius: 32rpx;
+		line-height: 64rpx;
+		text-align: center;
+		margin-right: 20rpx;
+	}
+	.bottomBox{
+		position: fixed;
+		bottom: 0;
+		width: 100%;
+		left: 0;
+		height:98rpx ;
+		background-color: #FFFFFF;
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		padding: 0 30rpx;
+	}
+	.blackFont{
+		color: #333333;
+		margin: 0 4rpx;
+	}
+	.wk_icon{
+		width: 24rpx;
+		height: 24rpx;
+		margin-right: 12rpx;
+	}
+	.noteTag{
+		ont-size: 24rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #999999;
+		align-items: center;
+	}
+	.priceTag{
+		font-size: 30rpx;
+		font-family: PingFang SC;
+		font-weight: bold;
+		color: #FF2D55;
+	}
+	.titleTag{
+		font-size: 32rpx;
+		font-weight: bold;
+		color: #333333;
+		margin-left: 8rpx;
+	}
+	.yearTag{
+		width: 80rpx;
+		height: 32rpx;
+		background: #EBF5FF;
+		border: 2rpx solid #007AFF;
+		border-radius: 16rpx;
+		font-size: 24rpx;
+		color: #007AFF;
+		text-align: center;
+		line-height: 32rpx;
+	}
+	.itemBox{
+		background: #FFFFFF;
+		box-shadow: 0rpx 10rpx 9rpx 1rpx rgba(165, 196, 239, 0.1);
+		border-radius: 24rpx;
+		width: 100%;
+		padding: 20rpx;
+		margin-bottom: 20rpx;
+	}
+</style>

+ 228 - 0
pages5/liveDetail/list.vue

@@ -0,0 +1,228 @@
+<template>
+	<view>
+		<nav-bar title="我的直播课"></nav-bar>
+		<view class="content">
+			<view class="content__header" v-if="livingSectionList[0]" @click="goLive(livingSectionList[0])">
+				<image class="img" src="../static/live.png" mode="widthFix"></image>
+				<view class="note">正在直播中</view>
+				<view class="title">{{livingSectionList[0].name}}</view>
+			</view>
+			<view class="content__body">
+				<view class="list">
+					<view class="item" v-for="(item,index) in list" :key="index" @click="go(item)">
+						<image  mode="widthFix" class="img" :src="$method.splitImgHost(item.coverUrl,false)"></image>
+						<view class="title">{{item.goodsName}}</view>
+						<view class="desc">
+							<image class="desc__img" src="../static/icon-list.png"></image>
+							共 <text>{{item.studyCount}}</text> 学时
+						</view>
+						<view class="desc">
+							<image  mode="widthFix" class="desc__img" src="../static/icon-time.png"></image>
+							直播日期:<text>{{$method.timestampToTime(item.liveStartTime)}} - {{$method.timestampToTime(item.liveEndTime)}}</text>
+						</view>
+						<view class="button">进入学习</view>
+					</view>
+					
+					<view v-if="list.length==0">
+						<u-empty text="暂无直播课" margin-top="500" mode="list"></u-empty>
+					
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+// import { websocket } from '@/common/socket.js';
+import {WEBVIEW_URL} from '@/common/request.js'
+import { mapGetters } from 'vuex';
+export default {
+	data() {
+		return {
+			list:[],
+			param:{
+				pageNum:1,
+				pageSize:10
+			},
+			livingSectionList:[],
+			total:0,
+		};
+	},
+	onUnload() {},
+	computed: { ...mapGetters(['userInfo']) },
+	onLoad(option) {
+		this.goodsListGoodsUserLive()
+		this.goodsLivingSectionList();
+	},
+	onShow() {},
+	onReachBottom() {
+		if (this.list.length < this.total) {
+			this.param.pageNum++;
+			this.goodsListGoodsUserLive();
+		}
+	},
+	methods: {
+		goodsLivingSectionList() {
+			this.$api.goodsLivingSectionList().then(res => {
+				this.livingSectionList = res.data.data;
+			})
+		},
+		goodsListGoodsUserLive() {
+			this.$api.goodsListGoodsUserLive(this.param).then(res => {
+				this.list.push(...res.data.rows)
+				this.total = res.data.total
+			})
+		},
+		goLive(item) {
+			let moduleId = item.moduleId || 0;
+			let chapterId = item.chapterId || 0;
+			let sectionId = item.sectionId || item.menuId;
+			let encode = encodeURIComponent(WEBVIEW_URL+'pages/live/index?token='+uni.getStorageSync('token')+'&userInfo='+JSON.stringify(this.userInfo)+'&channelId='+item.liveUrl+'&gradeId='+0+'&courseId='+this.courseId+'&goodsId='+this.goodsId+'&orderGoodsId='+this.orderGoodsId+'&sectionId='+sectionId+'&chapterId='+chapterId+'&moduleId='+moduleId)
+			uni.navigateTo({
+				url:`../../pages/webview/index?url=`+encode
+			})
+		},
+		go(item) {
+			this.$api.courseCourseList({
+				pageNum: 1,
+				pageSize: 1,
+				goodsId: item.goodsId,
+				gradeId: 0,
+				orderGoodsId: item.orderGoodsId,
+			}).then(res => {
+				if (res.data.code == 200) {
+					if(res.data.total > 1) {
+						uni.navigateTo({
+							url:'/pages5/liveDetail/course?orderGoodsId='+item.orderGoodsId+'&goodsId='+item.goodsId+'&gradeId=0'
+						})
+					} else if(res.data.total == 1) {
+						uni.navigateTo({
+							url:'/pages3/live/detail?orderGoodsId='+item.orderGoodsId+'&goodsId='+item.goodsId+'&gradeId=0&courseId='+ res.data.rows[0].courseId
+						})
+					} else {
+						uni.showToast({
+							icon:'none',
+							title:'暂无可观看的直播课程'
+						})
+					}
+				
+				}
+			});
+			
+		}
+	}
+};
+</script>
+<style>
+page {
+	background-color: #eaeef1;
+}
+</style>
+<style lang="scss" scope>
+.content {
+	padding:24rpx;
+	
+	&__header {
+		position:relative;
+		width:100%;
+		height:150rpx;
+		padding:24rpx 150rpx 24rpx 24rpx;
+		
+		.img {
+			position:absolute;
+			left:0;
+			top:0;
+			width:100%;
+		}
+		
+		.note {
+			position:relative;
+			z-index: 10;
+			font-size: 24rpx;
+			font-family: PingFang SC;
+			font-weight: bold;
+			color: #EFDBFF;
+		}
+		
+		.title {
+			position:relative;
+			z-index: 10;
+			font-size: 26rpx;
+			font-family: PingFang SC;
+			font-weight: bold;
+			color: #FFFFFF;
+		}
+		
+		.desc {
+			
+		}
+	}
+	
+	&__body {
+		.list {
+			.item {
+				margin-top:20rpx;
+				background: #fff;
+				padding: 24rpx;
+				box-shadow: 0px 10rpx 9rpx 1px rgba(165, 196, 239, 0.1);
+				border-radius: 24rpx;
+				
+				.img {
+					width: 654rpx;
+					height: 367rpx;
+					background: #E6EEFF;
+					border-radius: 16rpx;
+				}
+				
+				.title {
+					margin-top:10rpx;
+					font-size: 32rpx;
+					font-family: PingFang SC;
+					font-weight: bold;
+					color: #333333;
+					display: -webkit-box;
+					
+					-webkit-box-orient: vertical;
+
+					-webkit-line-clamp: 2;
+
+					overflow: hidden;
+				}
+				
+				.desc {
+					margin-top:10rpx;
+					font-size: 24rpx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #999999;
+					display: flex;
+					align-items: center;
+					
+					&__img {
+						margin-right:5rpx;
+						width:24rpx;
+						height:24rpx;
+					}
+					
+					text {
+						color:#666;
+					}
+				}
+				
+				.button {
+					margin-top:10rpx;
+					width: 100%;
+					height: 64rpx;
+					background: #007AFF;
+					border-radius: 16rpx;
+					text-align: center;
+					line-height: 64rpx;
+					color:#fff;
+					font-size: 28rpx;
+				}
+			}
+		}
+	}
+}
+</style>

+ 1 - 1
pages5/liveList/index.vue

@@ -195,7 +195,7 @@ page {
 	width: 100%;
 	display: flex;
 	z-index: 10;
-		background: #ffffff;
+	background: #ffffff;
 	.tab {
 		padding:0 18rpx;
 		flex: 1;

BIN
pages5/static/icon-list.png


BIN
pages5/static/icon-time.png


BIN
pages5/static/live.png


+ 5 - 1
store/index.js

@@ -22,6 +22,7 @@ const store = new Vuex.Store({
 		copyData: null, //存放审核资料数据
 		playChannelId: 0, //正在播放的直播频道号
 		playVID: 0, //正在播放的保利威视频ID
+		liveLast:null,
 	},
 	getters: {
 		userInfo: state => {
@@ -82,6 +83,7 @@ const store = new Vuex.Store({
 		getCopyData: state => state.copyData,
 		playChannelId: state => state.playChannelId,
 		playVID: state => state.playVID,
+		liveLast: state => state.liveLast,
 	},
 	mutations: {
 		tabNum(state, nums) {
@@ -95,7 +97,9 @@ const store = new Vuex.Store({
 					index: 3
 				})
 			}
-
+		},
+		updateLiveLast(state,liveLast) {
+			state.liveLast = liveLast
 		},
 		updateAllowLoading(state,isShowloading) {
 			state.allowLoading = isShowloading