xionghaojie пре 3 година
родитељ
комит
16c9aa4dc1
4 измењених фајлова са 325 додато и 97 уклоњено
  1. 56 0
      pages/selectTest/selectTest.css
  2. 172 8
      pages/selectTest/selectTest.vue
  3. 95 88
      pages/test/test.vue
  4. 2 1
      utils/request.js

+ 56 - 0
pages/selectTest/selectTest.css

@@ -179,3 +179,59 @@
 .note-item-date {
 	color: #999999;
 }
+
+/* 弹窗 */
+.popup-box{
+	width: 722px;
+	min-height: 326px;
+	background: #FFFFFF;
+	box-shadow: 0px 0px 10px 1px rgba(81,0,0,0.1);
+	border-radius: 6px 6px 6px 6px;
+	opacity: 1;
+	border: 3px solid #FFFFFF;
+}
+.popup-top{
+	height: 65px;
+	line-height: 65px;
+	padding: 0 25px 0 17px;
+	border-bottom: 1px solid #EBEBEB;
+	font-size: 14px;
+	justify-content: space-between;
+}
+.popup-top image{
+	width: 29px;
+	height: 29px;
+	cursor: pointer;
+}
+.popup-content{
+	text-align: center;
+	font-size: 16px;
+	margin-top: 30px;
+}
+.popup-bottom{
+	margin-top: 30px;
+	justify-content: center;
+	margin-bottom: 30px;
+}
+.popup-btn1{
+	width: 146px;
+	height: 42px;
+	line-height: 42px;
+	border-radius: 21px 21px 21px 21px;
+	opacity: 1;
+	border: 1px solid #999999;
+	text-align: center;
+	cursor: pointer;
+}
+.popup-btn2{
+	width: 146px;
+	height: 42px;
+	line-height: 42px;
+	border-radius: 21px 21px 21px 21px;
+	opacity: 1;
+	border: 1px solid #DF230F;
+	margin-left: 30px;
+	text-align: center;
+	color: #DF230F;
+	cursor: pointer;
+}

+ 172 - 8
pages/selectTest/selectTest.vue

@@ -68,6 +68,31 @@
 			</view>
 		</view>
 		
+		<uni-popup ref="popup" type="bottom" :is-mask-click='false'>
+			<view class="popup-box">
+				<view class="popup-top ddflex">
+					<view>身份验证</view>
+					<image src="/static/images/close.png" @click="close()"></image>
+				</view>
+				<view class="popup-content">您好!考试前需要进行身份验证,请手持准考证,对准摄像头进行拍照,示例如下</view>
+				<view style="width: 400px;height: 243px;margin:30px auto;" v-show="!isPhotoing&&!imageUrl">
+					<img style="width: 100%;height: 100%" src="/static/images/sfyz.png"/>
+				</view>
+				<view v-show="isPhotoing" style="width: 400px;height: 243px;margin:30px auto;position: relative;" id="video-box">
+					<video id="video" style="width: 100%;height: 100%;" object-fit='fill' :autoplay="true" :controls="false" :show-center-play-btn="false"></video>
+					<canvas id="canvas" style="width: 100%;height: 100%;position: absolute;top:100000px;"  canvas-id="canvas"></canvas>
+					<view style="position: absolute;top: 50%;left: 50%;transform: translate(-50%,-50%);z-index: 100;font-size: 50px;color: #1AA1E6;font-weight: bold;">{{timeText}}</view>
+				</view>
+				<view style="width: 400px;height: 243px;margin:30px auto;" v-show="!isPhotoing&&imageUrl">
+					<img style="width: 100%;height: 100%" :src="imageUrl"/>
+				</view>
+				<view class="popup-bottom ddflex">
+					<view class="popup-btn2" @click="yanzheng" v-show="!isPhotoing">{{imageUrl?'重新验证':'立即验证'}}</view>
+					<view class="popup-btn2" v-if="imageUrl" @click="yanzhengSubmit">确认</view>
+				</view>
+			</view>
+		</uni-popup>
+		
 		<Foot></Foot>
 	</view>
 </template>
@@ -90,7 +115,13 @@
 				
 				testList:[],
 				
-				userInfo:{}
+				userInfo:{},
+				
+				item:{},
+				isPhotoing:false,//是否正在验证身份
+				imageUrl:'',
+				timeText:3,
+				timeInterval:null
 			}
 		},
 		onReady() {},
@@ -127,19 +158,152 @@
 					content:`确定开始 ${item.title}?`,
 					success: (res) => {
 						if(res.confirm){
-							uni.navigateTo({
-								// url: '/pages/test/test?paperId='+this.paperId,
-								url: '/pages/test/test?paperId='+item.id+'&testId='+this.paperId,
-								success:()=> {
-									this.close()
-								}
-							});
+							// 如果进行身份验证
+							this.item = item
+							this.open()
+							
+							// 直接考试,是否允许考试
+							// uni.navigateTo({
+							// 	// url: '/pages/test/test?paperId='+this.paperId,
+							// 	url: '/pages/test/test?paperId='+item.id+'&testId='+this.paperId,
+							// 	success:()=> {
+							// 		this.close()
+							// 	}
+							// });
 						}else{
 							
 						}
 					}
 				})
 			},
+			open() {
+				this.$refs.popup.open('center')
+			},
+			close() {
+				this.$refs.popup.close()
+				clearInterval(this.timeInterval)
+				this.isPhotoing = false
+				this.imageUrl = ''
+			},
+			// 验证提交
+			yanzhengSubmit(){
+				let userPhotoData = {examId:this.paperId,image:this.imageUrl,paperId:this.item.id}
+				req.postRequest('/api/v3/exam/user/manager/image',userPhotoData,res=>{
+					uni.navigateTo({
+						// url: '/pages/test/test?paperId='+this.paperId,
+						url: '/pages/test/test?paperId='+this.item.id+'&testId='+this.paperId,
+						success:()=> {
+							this.close()
+						}
+					});
+				})
+			},
+			// 身份验证
+			yanzheng(){
+				this.imageUrl = ''
+				this.test()
+			},
+			takePhoto() {
+				let _this = this
+			    //获得Canvas对象
+				const query = uni.createSelectorQuery().in(this);
+			    let video = document.querySelector('video');
+				let canvas = document.querySelector('canvas')
+			    let ctx = canvas.getContext('2d');
+				let videoInfo = {}
+				query.select('video').boundingClientRect(result => {
+					console.log('videoInfo',result)
+					videoInfo={
+						width:result.width,
+						height:result.height
+					}
+				}).exec();
+			    ctx.drawImage(video, 0, 0, videoInfo.width, videoInfo.height);
+				// console.log(this.dataURLtoBlob(canvas.toDataURL(),'11'))
+				req.uploadFile('/api/upload', canvas.toDataURL(), res => {
+					// req.msg('图片上传成功');
+					console.log('图片上传成功',res)
+					// _this.imageUrl = canvas.toDataURL()
+					_this.imageUrl = res.src
+					_this.isPhotoing = false
+				},false);
+			},
+			test(){
+				// var video = document.querySelector('video');
+				const query = uni.createSelectorQuery().in(this);
+				var video = query.select('#video')
+				console.log('video',video)	
+				// 兼容代码
+				window.URL = (window.URL || window.webkitURL || window.mozURL || window.msURL);
+				// 获取媒体属性,旧版本浏览器可能不支持mediaDevices,我们首先设置一个空对象
+				if (navigator.mediaDevices === undefined) {
+				    navigator.mediaDevices = {};
+				}
+				console.log('navigator.mediaDevices',navigator.mediaDevices)
+				// 一些浏览器实现了部分mediaDevices,我们不能只分配一个对象
+				// 使用getUserMedia,因为它会覆盖现有的属性。
+				// 这里,如果缺少getUserMedia属性,就添加它。
+				if (navigator.mediaDevices.getUserMedia === undefined) {
+					navigator.mediaDevices.getUserMedia = function(constraints) {
+						// 首先获取现存的getUserMedia(如果存在)
+					    var getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
+						// 有些浏览器不支持,会返回错误信息
+						// 保持接口一致
+					    if (!getUserMedia) { //不存在则报错
+					        return Promise.reject(new Error('getUserMedia is not implemented in this browser'));
+					    }
+						// 否则,使用Promise将调用包装到旧的navigator.getUserMedia
+					    return new Promise(function(resolve, reject) {
+					        getUserMedia.call(navigator, constraints, resolve, reject);
+					    });
+					}
+				}
+				//摄像头调用配置
+				var mediaOpts = {
+				    audio: false,
+				    video: { facingMode: "user"} 
+				    
+				}
+							 
+				let that=this;
+				navigator.mediaDevices.getUserMedia(mediaOpts).then(function(stream) {
+				    that.mediaStreamTrack = stream;
+				    video = document.querySelector('video');
+					console.log('video = document.querySelector(video);',video)
+						// 旧的浏览器可能没有srcObject
+				    if ("srcObject" in video) {
+				        video.srcObject = stream
+				    } else {
+						// 避免在新的浏览器中使用它,因为它正在被弃用。
+				        video.src = window.URL && window.URL.createObjectURL(stream) || stream
+				    }
+				    video.play();
+					that.isPhotoing = true
+					that.timeText = 3
+					that.timeInterval = setInterval(()=>{
+						if(that.timeText>0){
+							that.timeText--
+						}else{
+							clearInterval(that.timeInterval)
+							that.timeInterval= null
+							that.takePhoto()
+						}
+					},1000)
+				}).catch(function (err) {
+				    console.log(err)
+					uni.showModal({
+						title:'提示',
+						content:'未找到摄像头',
+						showCancel:false,
+						success() {
+							// uni.navigateBack({
+								
+							// })
+						}
+					})
+				});
+			},
+			
 			// 成绩查询
 			queryScore(item){
 				var formP = {

+ 95 - 88
pages/test/test.vue

@@ -5,11 +5,11 @@
 			<view style="width: 1200px;margin: auto;">{{paper.title}}</view>
 		</view>
 		
-		<view class="video-box" id="video-box" @click="takePhoto" v-show="showVideo">
+		<view class="video-box" id="video-box" v-show="showVideo">
 			<video id="video" style="width: 100%;height: 100%;" :autoplay="true" :controls="false" :show-center-play-btn="false"></video>
-			<canvas id="canvas" style="width: 100%;height: 100%;"  canvas-id="canvas"></canvas>
+			<canvas id="canvas" style="width: 100%;height: 100%;position: absolute;top:100000px;"  canvas-id="canvas"></canvas>
 		</view>
-		<img  :src="imgUrl" ></img>
+		<!-- <img  :src="imgUrl" ></img> -->
 		<view class="project-content ddflex">
 			<!-- 考试区域 -->
 			<view class="test-box">
@@ -204,23 +204,25 @@
 				canvas:null,
 				ctx:null,
 				imgUrl:null,
-				showVideo:false
+				showVideo:false,
+				
+				takePhotoTime:10*60,//抓拍时间间隔,单位s
 			}
 		},
 		onReady() {},
 		async onLoad(options) {
 			this.paperId = options.paperId;
 			this.testId = options.testId
+			// 摄像头
+			const query = uni.createSelectorQuery().in(this);
+			this.video = query.select('#video')
+			this.canvas = query.select('#canvas');
+			await this.test()
 
 			console.log(this.userInfo)
 			// 需要先判断用户是否还能考试
 			await this.getQuests();
 			
-			// 摄像头
-			// const query = uni.createSelectorQuery().in(this);
-			// this.video = query.select('#video')
-			// this.canvas = query.select('#canvas');
-			// this.test()
 			
 			
 			// 考生信息
@@ -231,6 +233,7 @@
 		},
 		onUnload() {
 				// uni.clearStorageSync();
+				clearTimeout(this.ptime);
 		},
 		methods: {
 			// 考试信息
@@ -348,8 +351,18 @@
 				_ts.times = times;
 				_ts.ptime = setTimeout(function() {
 					_ts.time = time - 1;
+					
+					
+					if(((_ts.paper.time*60)-(_ts.time))%(_ts.takePhotoTime)==0){
+						_ts.takePhoto()
+					}
 					_ts.setTime();
 				}, 1000);
+				
+				// if(((_ts.paper.time*60) -(_ts.time*60)%(10))%(10)==0){
+				// 	let a = (_ts.paper.time*60) -(_ts.time*60)%(10)
+				// 	console.log((_ts.paper.time*60) -(_ts.time*60),'拍照')
+				// }
 			}, //下次继续
 			// 秒转换时分秒
 			timeChangeHMS(time){
@@ -621,22 +634,13 @@
 					}
 				}).exec();
 			    ctx.drawImage(video, 0, 0, videoInfo.width, videoInfo.height);
-				console.log(this.dataURLtoBlob(canvas.toDataURL(),'11'))
-				// setTimeout(() => {
-				// 	uni.canvasToTempFilePath({
-				// 		canvasId: 'canvas',
-				// 		destWidth: 60,
-				// 		destHeight: 40,
-				// 		success: function (res) {
-				// 			console.log(res.tempFilePath) //图片路径
-				// 			// resolve(res.tempFilePath)
-				// 			_this.imgUrl = res.tempFilePath
-				// 		},
-				// 		fail: function (res) {
-				// 			console.log(res.errMsg)
-				// 		}
-				// 	})
-				// }, 100)
+				// console.log(this.dataURLtoBlob(canvas.toDataURL(),'11'))
+				req.uploadFile('/api/upload', canvas.toDataURL(), res => {
+					let userPhotoData = {examId:this.testId,image:res.src,paperId:this.paperId}
+					req.postRequest('/api/v3/exam/user/manager/image',userPhotoData,res=>{
+						
+					})
+				},false);
 			},
 			dataURLtoBlob(dataurl) {
 			                            var arr = dataurl.split(','),
@@ -667,71 +671,74 @@
 				});
 			},
 			test(){
-				// var video = document.querySelector('video');
-				const query = uni.createSelectorQuery().in(this);
-				var video = query.select('#video')
-				console.log('video',video)	
-				// 兼容代码
-				window.URL = (window.URL || window.webkitURL || window.mozURL || window.msURL);
-				// 获取媒体属性,旧版本浏览器可能不支持mediaDevices,我们首先设置一个空对象
-				if (navigator.mediaDevices === undefined) {
-				    navigator.mediaDevices = {};
-				}
-				console.log('navigator.mediaDevices',navigator.mediaDevices)
-				// 一些浏览器实现了部分mediaDevices,我们不能只分配一个对象
-				// 使用getUserMedia,因为它会覆盖现有的属性。
-				// 这里,如果缺少getUserMedia属性,就添加它。
-				if (navigator.mediaDevices.getUserMedia === undefined) {
-					navigator.mediaDevices.getUserMedia = function(constraints) {
-						// 首先获取现存的getUserMedia(如果存在)
-					    var getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
-						// 有些浏览器不支持,会返回错误信息
-						// 保持接口一致
-					    if (!getUserMedia) { //不存在则报错
-					        return Promise.reject(new Error('getUserMedia is not implemented in this browser'));
-					    }
-						// 否则,使用Promise将调用包装到旧的navigator.getUserMedia
-					    return new Promise(function(resolve, reject) {
-					        getUserMedia.call(navigator, constraints, resolve, reject);
-					    });
+				return new Promise((r,j)=>{
+					// var video = document.querySelector('video');
+					const query = uni.createSelectorQuery().in(this);
+					var video = query.select('#video')
+					console.log('video',video)	
+					// 兼容代码
+					window.URL = (window.URL || window.webkitURL || window.mozURL || window.msURL);
+					// 获取媒体属性,旧版本浏览器可能不支持mediaDevices,我们首先设置一个空对象
+					if (navigator.mediaDevices === undefined) {
+					    navigator.mediaDevices = {};
 					}
-				}
-				//摄像头调用配置
-				var mediaOpts = {
-				    audio: false,
-				    video: { facingMode: "user"} 
-				    
-				}
-							 
-				let that=this;
-				navigator.mediaDevices.getUserMedia(mediaOpts).then(function(stream) {
-				    that.mediaStreamTrack = stream;
-				    video = document.querySelector('video');
-					console.log('video = document.querySelector(video);',video)
-						// 旧的浏览器可能没有srcObject
-				    if ("srcObject" in video) {
-				        video.srcObject = stream
-						that.video.srcObject = stream
-				    } else {
-						// 避免在新的浏览器中使用它,因为它正在被弃用。
-				        video.src = window.URL && window.URL.createObjectURL(stream) || stream
-						that.video.src = window.URL && window.URL.createObjectURL(stream) || stream
-				    }
-				    video.play();
-					that.showVideo = true
-				}).catch(function (err) {
-				    console.log(err)
-					uni.showModal({
-						title:'提示',
-						content:'未找到摄像头',
-						showCancel:false,
-						success() {
-							// uni.navigateBack({
-								
-							// })
+					console.log('navigator.mediaDevices',navigator.mediaDevices)
+					// 一些浏览器实现了部分mediaDevices,我们不能只分配一个对象
+					// 使用getUserMedia,因为它会覆盖现有的属性。
+					// 这里,如果缺少getUserMedia属性,就添加它。
+					if (navigator.mediaDevices.getUserMedia === undefined) {
+						navigator.mediaDevices.getUserMedia = function(constraints) {
+							// 首先获取现存的getUserMedia(如果存在)
+						    var getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
+							// 有些浏览器不支持,会返回错误信息
+							// 保持接口一致
+						    if (!getUserMedia) { //不存在则报错
+						        return Promise.reject(new Error('getUserMedia is not implemented in this browser'));
+						    }
+							// 否则,使用Promise将调用包装到旧的navigator.getUserMedia
+						    return new Promise(function(resolve, reject) {
+						        getUserMedia.call(navigator, constraints, resolve, reject);
+						    });
 						}
-					})
-				});
+					}
+					//摄像头调用配置
+					var mediaOpts = {
+					    audio: false,
+					    video: { facingMode: "user"} 
+					    
+					}
+								 
+					let that=this;
+					navigator.mediaDevices.getUserMedia(mediaOpts).then(function(stream) {
+					    that.mediaStreamTrack = stream;
+					    video = document.querySelector('video');
+						console.log('video = document.querySelector(video);',video)
+							// 旧的浏览器可能没有srcObject
+					    if ("srcObject" in video) {
+					        video.srcObject = stream
+							that.video.srcObject = stream
+					    } else {
+							// 避免在新的浏览器中使用它,因为它正在被弃用。
+					        video.src = window.URL && window.URL.createObjectURL(stream) || stream
+							that.video.src = window.URL && window.URL.createObjectURL(stream) || stream
+					    }
+					    video.play();
+						that.showVideo = true
+						r()
+					}).catch(function (err) {
+					    console.log(err)
+						uni.showModal({
+							title:'提示',
+							content:'未找到摄像头',
+							showCancel:false,
+							success() {
+								uni.navigateBack({
+									
+								})
+							}
+						})
+					});
+				})
 			},
 		},
 	}

+ 2 - 1
utils/request.js

@@ -11,7 +11,8 @@ const env = {
 	pota: {
 		// apiUrl: 'http://192.168.110.248:7012' //y
 		// apiUrl: 'http://192.168.110.97:7012' ,//w
-		apiUrl:'http://192.168.110.109:7012',//w
+		// apiUrl:'http://192.168.110.109:7012',//w
+		apiUrl: 'http://192.168.110.176:8098' ,//y
 	}
 }