Browse Source

2024年11月27日更新

lvmax 3 months ago
parent
commit
249a201e5b
4 changed files with 194 additions and 99 deletions
  1. 11 2
      pages/examPage/examInfo.vue
  2. 149 77
      pages/examPage/examStart.vue
  3. 32 20
      pages/login/Login.vue
  4. 2 0
      util/examStartUtil.js

+ 11 - 2
pages/examPage/examInfo.vue

@@ -133,7 +133,16 @@
 			</button>
 		</view>
 	</view>
-
+<uni-popup ref="inputDialog" type="dialog">
+		<uni-popup-dialog style="width: 50vh;" ref="inputClose" title="考生信息" >
+			<view >
+				<view style="text-align: center;"><strong>姓名:</strong><strong>{{ user.realname }}</strong></view>
+				<view></view>
+				<view style="text-align: center;"><strong>考号</strong><strong>{{ user.username }}</strong></view>
+				<view></view>				
+			</view>
+		</uni-popup-dialog>
+	</uni-popup>
 </template>
 
 <script>
@@ -183,7 +192,7 @@
 				if (this.exams.length === 1) {
 					this.enterExam(0)
 				}
-
+this.$refs.inputDialog.open()
 			}).catch(xhr => {
 				console.log(xhr);
 			});

+ 149 - 77
pages/examPage/examStart.vue

@@ -27,17 +27,14 @@
 							<view class="paperCss"
 								:style="'background-color: '+(item.state === 0?'#b5aa09;':(item.state === 9?'#ececec':'#00f545'))">
 								<view style="color: #000000;"> <strong>{{item.title}}</strong></view>
-								<!-- <view >剩余</view> -->
-
-
 							</view>
 						</view>
 					</label>
 				</radio-group>
 				<l-divider color="#b3b3b3">
-
 				</l-divider>
 				<button type="primary" style="margin-top: 10px;" @click="subExam">交卷</button>
+				<button type="primary" style="margin-top: 10px;" @click="reload">刷新</button>
 			</uni-card>
 
 		</uni-col>
@@ -339,7 +336,7 @@
 									style="height: 600px;width: 800px;background-color: #8c8c8c;margin: auto;padding-top: 50px;">
 
 									<movable-area
-										style="height: 500px;width: 700px;background-color: #f6f6f6;margin: auto;">
+										style="height: 550px;width: 700px;background-color: #f6f6f6;margin: auto;">
 										<canvas canvas-id="lineCanvas" style="width: 700px; height: 500px;">
 											<template v-for="(item,index)  in connectionHtml">
 												<view
@@ -347,9 +344,7 @@
 													<!-- <rich-text :nodes="item.innerHTML"></rich-text> -->
 													<view v-for="(item0,index0) in item.children" :key="index">
 														<view :id="'option'+index+'-'+(index0+1)"
-															style="padding-left: 10px;padding-right: 10px;padding-top: 10px;border-radius: 5px;margin-bottom: 10px;border: #007aff solid 1px;background-color: #e0eef9;">
-															<!-- 	<rich-text :nodes="item0.innerHTML"
-																></rich-text> -->
+															style="width: 90px;height: 100px;padding: 10px;padding-bottom:0 ;margin-bottom: 10px;border-radius: 5px;border: #007aff solid 1px;background-color: #e0eef9;overflow: hidden;">
 														</view>
 													</view>
 												</view>
@@ -362,7 +357,6 @@
 					</uni-section>
 				</scroll-view>
 			</uni-card>
-
 		</uni-col>
 		<uni-col :span="4" style="margin-top: 30px">
 			<uni-card style="height: 85vh;">
@@ -371,8 +365,8 @@
 					<view style="font-size: 20px;">当前试卷时间</view>
 				</l-divider>
 				<view
-					style="font-family: '微软雅黑', serif;font-size: 20px;color: #f90005;height: 30px;text-align: center;padding:10px;">
-					剩余:{{paperTime}}
+					style="font-family: '微软雅黑', serif;font-size: 20px;color: #f90005;height: 30px;text-align: center;padding:10px;font-size: 35px;">
+					<strong>{{paperTime}}</strong>
 				</view>
 				<!-- 	<l-divider color="#8f960c">
 					<view style="font-size: 20px;">考试时间</view>
@@ -390,9 +384,10 @@
 						<label v-for="(item, index) in  examObject.answerCardList2" :key="item">
 							<uni-section class="mb-10" :title="item.questionTypeName" type="line">
 								<template v-for="sort in item.indexList">
-									<view style="display: inline-block;margin-left: 5px;">
+									<view style="display: inline-block;margin-left: 5px;"
+										@mousedown="radioScantron(sort)">
 										<view>
-											<button type="radio" @click="radioScantron(sort)"
+											<button type="radio"
 												:style="'width: 30px;height: 30px;padding:0px;color:#FFFFFF;font-size: 12px;text-align: center;background-color: '+(sort === scantron.questionIndex?'#b5aa09;':(this.examObject.userExamQuestionList[sort-1].question.isAnswer?'#18da59':'#007aff'))">{{sort}}</button>
 										</view>
 										<view>
@@ -426,7 +421,15 @@
 				<view>2、本试卷剩余时间不计入下一套</view>
 				<view>3、最终试卷提交将结束考试</view>
 				<view style="text-align: center;">确认提交?</view>
-
+			</view>
+		</uni-popup-dialog>
+	</uni-popup>
+	<uni-popup ref="cheat" type="dialog">
+		<uni-popup-dialog style="width: 50vh;" ref="inputClose" title="作弊提醒">
+			<view style="color: red;">
+				<view>1、鼠标请勿点击窗口之外的地方</view>
+				<view>2、如果不小心退出全屏,请按F11恢复到全屏</view>
+				<view>3、鼠标多次点击窗口之外的地方将按作弊处理</view>
 			</view>
 		</uni-popup-dialog>
 	</uni-popup>
@@ -447,24 +450,20 @@
 		redirectTo,
 		toLogin
 	} from '../../examJs/examRoute';
+	import {
+		windowState
+	} from '../../util/examStartUtil';
 	export default {
 		name: "examStart",
 		data() {
 			return {
 				// 所有方块============拖拽
-				drag: [{
-					answer: [],
-					option: [],
-					background: {
-						url: '',
-						width: 100,
-						height: 100
-					}
-				}],
-				mbvShow:true,
+				drag: [],
+				// 拖拽元素刷新
+				mbvShow: true,
 				// 拖拽的方块信息
 				dragItem: {},
-				// 拖拽记录
+				// 拖拽位置记录
 				subDrag: [],
 				// 拖拽后动作未完成禁用
 				disabledDrag: true,
@@ -474,11 +473,13 @@
 				connectionHtml: [],
 				// 连线题中间存储
 				connectionInfo: [],
-				// 连线题连线内容
+				// 连线题连线内容保存
 				connectionContentALL: [],
 				// 连线绘制
 				ctx: null,
+				// 点击过程颜色
 				clickColor: '0px 0px 5px 2px rgba(80, 85, 83, 0.7)',
+				// 点击结束颜色
 				connectionColor: ['#ffaa00', '#00ff7f', '#6ca7ff', '#1d00ff', '#aa00ff', '#ffff00', '#550000', '#ff0000'],
 				// ==============================
 				// 所有试卷和试题
@@ -492,12 +493,10 @@
 				typeThree: '',
 				userExamAnswers: [],
 				user: {},
-
 				// 拖动监听测试
 				b: true,
 				canvasWidth: 300,
 				canvasHeight: 300,
-
 				// 用户当前考试
 				userExamPaper: {},
 				// 倒计时实际时间
@@ -510,12 +509,30 @@
 				examTime: '',
 				// 倒计时函数
 				intervalId: null,
+				// 切屏记录========================
+				windowCheat: 0,
+				// 切屏状态
+				cheat: null,
+				// 消息弹窗记录=================
 				msgType: 'success',
 				messageText: '这是一条成功提示',
 			};
 		},
-
 		methods: {
+			// 页面刷新
+			reload() {
+				cacheExamAnswer({
+					'examAnswers': this.userExamAnswers,
+					'userExamId': sessionStorage.getItem('examId'),
+					'leaveTime': this.windowCheat,
+					'paperId': this.userExamPaper.paperId,
+					'limitTime': this.userExamPaper.limitTime
+				}).then(data => {
+					console.log(data);
+					window.location.reload()
+				})
+
+			},
 			// 消息提示
 			messageToggle(type, message) {
 				this.msgType = type
@@ -533,14 +550,14 @@
 			},
 			// 提交试卷
 			submitExam(ins) {
+				console.log(ins);
 				submitExamPaper({
 					'examAnswers': this.userExamAnswers,
 					'userExamId': sessionStorage.getItem('examId'),
 					'paperId': this.userExamPaper.paperId,
 				}).then(data => {
-
 					if (data.data.result !== null && data.data.success) {
-						if (ins !== 0) {
+						if (ins !== 0 && ins !== 'cheat') {
 							this.messageToggle('success', "本试卷提交成功,即将开始下一张试卷······")
 						}
 						this.userExamAnswers = []
@@ -556,20 +573,25 @@
 						this.intervalId = setInterval(this.updateCountDown, 1000);
 						this.examTime = this.paperTime
 					} else {
-						if (ins !== 0) {
+						if (ins === 'cheat') {
+							this.messageToggle('error', "多次切屏,考试强行终止")
+						} else if (ins !== 0) {
 							this.messageToggle('success', "考试已结束,即将退出!")
 						} else {
 							this.messageToggle('warn', "时间已到,已为您自动交卷")
 						}
 						setTimeout(() => {
 							screenfull.exit();
+							window.removeEventListener('blur', this.handleBlur);
+							window.removeEventListener('focus', this.handleFocus);
 							exit()
 						}, 2000)
 					}
-				})
+					if (data.data.result !== null && data.data.success && ins === 'cheat') {
+						this.handleBlur(0)
+					}
 
-			},
-			paper() {
+				})
 
 			},
 			// 重置
@@ -580,14 +602,12 @@
 				let content = this.stringToHTML(this.scantron.question.content)
 				console.log(content);
 				for (var i = 0; i < content.children.length; i++) {
-
 					let thisTop = content.children[i].style.top.toString().replace("px", "")
 					let thisLeft = content.children[i].style.left.toString().replace("px", "")
 					let thisWidth = content.children[i].style.width.toString().replace("px", "")
 					let thisHeight = content.children[i].style.height.toString().replace("px", "")
 					let thisBackgroundColor = content.children[i].style.backgroundColor
 					let thisInnerHTML = content.children[i].innerHTML
-					console.log(thisInnerHTML);
 					if (content.children[i].id.includes("option")) {
 						this.drag[this.scantron.sort].option.push({
 							id: content.children[i].id,
@@ -638,7 +658,6 @@
 			},
 			// 答题卡单击题目
 			radioScantron(value) {
-
 				this.scantron = this.examObject.userExamQuestionList[value - 1]
 				if (this.scantron.questionType !== 7 && this.scantron.questionType !== 8) {
 					document.getElementById('scantronNodes').innerHTML = this.scantron.question.content
@@ -661,12 +680,13 @@
 				cacheExamAnswer({
 					'examAnswers': this.userExamAnswers,
 					'userExamId': sessionStorage.getItem('examId'),
+					'leaveTime': this.windowCheat,
 					'paperId': this.userExamPaper.paperId,
 					'limitTime': this.userExamPaper.limitTime
 				})
 				// 拖拽加载
 				if (this.scantron.questionType == 7) {
-					this.mbvShow=!this.mbvShow
+					this.mbvShow = !this.mbvShow
 					this.disabledDrag = true
 					console.log(this.drag[this.scantron.questionIndex]);
 					if (this.drag[this.scantron.questionIndex] !== undefined) {
@@ -766,21 +786,23 @@
 					}, 100)
 					for (var i = 0; i < this.connectionHtml.length; i++) {
 						let option = this.connectionHtml[i]
-						console.log(option);
 						for (var j = 0; j < option.children.length; j++) {
 							let ids = "option" + i + "-" + (j + 1)
 							if (document.getElementById(ids) === null) {
 								setTimeout(() => {
 									let optionCol = document.getElementById(ids)
 									optionCol.addEventListener("mousedown", (event) => {
-										this.shadowClean()
+										console.log(event);
 
 										let id = event.currentTarget.id
+										console.log(id);
 										let colId = Number(id.replace('option', '').split('-')[0])
 										let rowId = Number(id.replace('option', '').split('-')[1])
 										let left = event.target.offsetLeft
-										let right = event.target.offsetLeft + event.target.width
-										let top = event.target.offsetTop + event.target.height / 2
+										let right = Number(event.target.offsetLeft + event.target
+											.offsetWidth)
+										let top = Number(event.target.offsetTop + event.target
+											.offsetHeight / 2)
 										if (this.connectionInfo.length === this.connectionHtml.length &&
 											colId === 0) {
 											this.connectionContentALL[this.scantron.sort].push(this
@@ -805,6 +827,7 @@
 											if (infoLength !== 0) {
 												if (!this.isLine(id, this.scantron.sort)) {
 													this.messageToggle('error', "这个已经连过了")
+													this.drawLineWrite(this.scantron.sort)
 													return
 												}
 												let last = this.connectionInfo[infoLength -
@@ -819,7 +842,8 @@
 														'top': top
 													})
 												}
-												if (lastId === colId&&colId!==this.connectionHtml.length-1) {
+												if (lastId === colId && colId !== this.connectionHtml
+													.length - 1) {
 													this.connectionInfo[infoLength - 1] = {
 														'id': id,
 														'left': left,
@@ -841,18 +865,18 @@
 															.split('-')[1], this.scantron)
 														this.connectionInfo = []
 													}
-												}else if(colId===this.connectionHtml.length-1){
-													
-														this.connectionContentALL[this.scantron.sort].push(
-															this.connectionInfo)
-														console.log(this.connectionContentALL[this.scantron
-															.sort]);
-														this.radioAdd(this.connectionInfo, this
-															.connectionInfo[0].id.replace('option', '')
-															.split('-')[1], this.scantron)
-														this.connectionInfo = []
+												} else if (colId === this.connectionHtml.length - 1) {
+
+													this.connectionContentALL[this.scantron.sort].push(
+														this.connectionInfo)
+													console.log(this.connectionContentALL[this.scantron
+														.sort]);
+													this.radioAdd(this.connectionInfo, this
+														.connectionInfo[0].id.replace('option', '')
+														.split('-')[1], this.scantron)
+													this.connectionInfo = []
 												}
-												
+
 
 											} else if (infoLength === 0) {
 												if (colId === 0) {
@@ -870,7 +894,10 @@
 
 											}
 										}
+										this.shadowClean()
 										this.drawLineWrite(this.scantron.sort)
+
+
 									})
 								}, 10)
 							} else {
@@ -916,7 +943,7 @@
 				const canvas = uni.createCanvasContext('lineCanvas');
 				// 使用clearRect方法清空整个画布
 				canvas.clearRect(0, 0, 700, 500); // 这里的300x300是画布的宽高,应该与你的实际画布尺寸相匹配
-				canvas.draw(); // 调用draw方法将清空操作应用到画布上
+				canvas.draw(true); // 调用draw方法将清空操作应用到画布上
 			},
 			// 阴影清理
 			shadowClean() {
@@ -947,7 +974,7 @@
 					let option = this.connectionHtml[i]
 					for (var j = 0; j < option.children.length; j++) {
 						let ids = "option" + i + "-" + (j + 1)
-						console.log(option.children[j].innerHTML);
+
 						document.getElementById(ids).innerHTML = option.children[j].innerHTML
 					}
 				}
@@ -963,6 +990,8 @@
 						document.getElementById(two.id).style.boxShadow = this.clickColor
 						this.drawLine(one.right, one.top, two.left, two.top, -1)
 					}
+				} else if (this.connectionInfo.length === 1) {
+					document.getElementById(this.connectionInfo[0].id).style.boxShadow = this.clickColor
 				}
 
 				for (var i = 0; i < this.connectionContentALL[value].length; i++) {
@@ -1067,7 +1096,7 @@
 			},
 			//缓存答案读取
 			answerDisplay(data) {
-
+				this.windowCheat = Number(data.leaveTime)
 				this.userExamAnswers = data.examAnswers
 
 				let examAnswers = data.examAnswers
@@ -1075,10 +1104,14 @@
 					let scantron = examAnswers[i]
 					let index = Number(scantron.index)
 					if (scantron.index.includes('.')) {
-						scantron.questionType = 6
-					}
+						let parentIndex = Number(scantron.index.split('.')[0])
+						let childIndex = scantron.index.split('.')[1]
+						let childSubject = this.examObject.userExamQuestionList[parentIndex - 1].subQuestionList[
+							childIndex]
 
-					if (scantron.questionType === 1 || scantron.questionType === 3) {
+						console.log(childSubject);
+
+					} else if (scantron.questionType === 1 || scantron.questionType === 3) {
 						console.log(this.examObject.userExamQuestionList[index - 1]);
 						this.examObject.userExamQuestionList[index - 1].question.isAnswer = true
 						this.examObject.userExamQuestionList[index - 1].question.answerList[Number(scantron.answerIndex[
@@ -1107,11 +1140,7 @@
 								}
 							}
 						}
-					} else if (scantron.questionType === 6) {
-
 					} else if (scantron.questionType === 7) {
-
-console.log(scantron);
 						this.examObject.userExamQuestionList[index - 1].question.isAnswer = true
 						let blankAnswer = JSON.parse(scantron.blankAnswer)
 						for (var k = 0; k < blankAnswer.length; k++) {
@@ -1157,7 +1186,6 @@ console.log(scantron);
 					scantron.question.answerList[index].isRight = true
 					for (var i = 0; i < this.userExamAnswers.length; i++) {
 						if (this.userExamAnswers[i].index !== qIndex) {
-
 							arr.push(this.userExamAnswers[i])
 						}
 					}
@@ -1268,9 +1296,7 @@ console.log(scantron);
 									questionType: scantron.questionType
 								})
 							} else {
-
 								this.examObject.userExamQuestionList[scantron.questionIndex - 1].question.isAnswer = false
-
 							}
 
 						}
@@ -1424,6 +1450,10 @@ console.log(scantron);
 							if (value === null || value === "") {
 								this.examObject.userExamQuestionList[scantron.questionIndex - 1].question.isAnswer = false
 							}
+							console.log(qIndex);
+							console.log(scantron);
+							console.log(this.examObject.userExamQuestionList[scantron.questionIndex - 1].subQuestionList[
+								Number(combinationItem.sort)]);
 							arr.push({
 								blankAnswer: JSON.stringify([{
 									tag: index,
@@ -1470,7 +1500,7 @@ console.log(scantron);
 							if (arrAnswer.length !== 0) {
 								arr.push({
 									blankAnswer: JSON.stringify(arrAnswer),
-									coordinates:JSON.stringify(this.drag[qIndex]),
+									coordinates: JSON.stringify(this.drag[qIndex]),
 									index: qIndex,
 									questionType: scantron.questionType
 								})
@@ -1489,7 +1519,7 @@ console.log(scantron);
 								tag: index,
 								content: value.id
 							}]),
-							coordinates:JSON.stringify(this.drag[qIndex]),
+							coordinates: JSON.stringify(this.drag[qIndex]),
 							index: qIndex,
 							questionType: scantron.questionType
 						})
@@ -1570,13 +1600,39 @@ console.log(scantron);
 				this.userExamAnswers = arr
 			},
 			// 失去焦点时的处理函数
-			handleBlur() {
-				// console.log('窗口失去焦点');
+			handleBlur(v) {
+				if (this.examObject.leaveOn) {
+					if (this.windowCheat < 2 && v !== 0) {
+						this.$refs.cheat.open()
+					}
+					let leaveCount = this.examObject.totalLeaveTimes
+					let leaveTime = this.examObject.leaveTime
+					if (this.windowCheat < leaveCount) {
+						this.cheat = setInterval(() => {
+							console.log("切屏加一");
+							this.windowCheat++
+							cacheExamAnswer({
+								'examAnswers': this.userExamAnswers,
+								'userExamId': sessionStorage.getItem('examId'),
+								'leaveTime': this.windowCheat,
+								'paperId': this.userExamPaper.paperId,
+								'limitTime': this.userExamPaper.limitTime
+							})
+							clearInterval(this.cheat)
+						}, leaveTime * 1000)
+					} else {
+						this.submitExam('cheat')
+					}
+
+					console.log(this.windowCheat);
+				}
 			},
 
 			// 获得焦点时的处理函数
 			handleFocus() {
-				// console.log('窗口获得焦点');
+				if (this.examObject.leaveOn) {
+					clearInterval(this.cheat)
+				}
 			},
 			// 时间
 			addExamPaperTime(systemTime, endTime) {
@@ -1637,6 +1693,21 @@ console.log(scantron);
 			}
 		},
 		mounted() {
+			window.addEventListener("unload", (e) => {
+				e.preventDefault();
+				setTimeout(() => {
+					cacheExamAnswer({
+						'examAnswers': this.userExamAnswers,
+						'userExamId': sessionStorage.getItem('examId'),
+						'leaveTime': this.windowCheat,
+						'paperId': this.userExamPaper.paperId,
+						'limitTime': this.userExamPaper.limitTime
+					}).then(data => {
+						console.log(data);
+					})
+				}, 100)
+			});
+
 			this.user = JSON.parse(sessionStorage.getItem("user"))
 			let examId = sessionStorage.getItem('examId')
 			getExamDetail({
@@ -1656,10 +1727,11 @@ console.log(scantron);
 				this.papersTime = this.examPapersTime()
 				this.intervalId = setInterval(this.updateCountDown, 1000);
 				this.examTime = this.paperTime
-				// 添加事件监听
-				window.addEventListener('blur', this.handleBlur);
-				window.addEventListener('focus', this.handleFocus);
-
+				// 添加切屏事件监听
+				if (windowState) {
+					window.addEventListener('blur', this.handleBlur);
+					window.addEventListener('focus', this.handleFocus);
+				}
 				// 获取缓存答案
 				getCacheAnswer({
 					'userExamId': examId

+ 32 - 20
pages/login/Login.vue

@@ -31,6 +31,11 @@
 				<view class="flex-item uni-bg-blue">
 				</view>
 			</view>
+			<view style="position: fixed;right: 10px;bottom: 10px;background-color: #c1c1c1;width: 300px;height: 200px;">
+				<a href="https://down.360safe.com/se/qd/360se_setup__sembg100031.exe">360浏览器</a>
+				<br/>
+				<a href="https://c2rsetup.officeapps.live.com/c2r/downloadEdge.aspx?platform=Default&source=EdgeStablePage&Channel=Stable&language=zh-cn&brand=M100">edge浏览器</a>
+			</view>
 		</view>
 	</view>
 
@@ -39,9 +44,10 @@
 	import {
 		getSysLogin,
 		request,
-
 	} from '../../examJs/examRequest';
-import { redirectTo } from '../../examJs/examRoute';
+	import {
+		redirectTo
+	} from '../../examJs/examRoute';
 
 	export default {
 		data() {
@@ -63,27 +69,33 @@ import { redirectTo } from '../../examJs/examRoute';
 				this.$refs.message.open()
 			},
 			submitUser() {
+				if (this.form.name.toString().trim().length === 0) {
+					this.messageToggle('error', "账号不能为空")
+					return
+				}
 				getSysLogin({
-					captcha: "",
-					loginType: 2,
-					password: "123456",
-					username: this.form.name,
-					t: Date.now()
-				}).then(data => {
+						captcha: "",
+						loginType: 2,
+						password: "123456",
+						username: this.form.name,
+						t: Date.now()
+					}).then(data => {
 
-					if (data.data.code === 200) {
-						this.messageToggle('success', data.data.message)
-						sessionStorage.setItem("token", data.data.result.token)
-						let user = JSON.stringify(data.data.result.userInfo)
-						sessionStorage.removeItem("user")
-						sessionStorage.setItem("user", user)
-						redirectTo('/pages/examPage/examInfo');
+						if (data.data.code === 200) {
+							this.messageToggle('success', data.data.message)
+							sessionStorage.setItem("token", data.data.result.token)
+							let user = JSON.stringify(data.data.result.userInfo)
+							sessionStorage.removeItem("user")
+							sessionStorage.setItem("user", user)
+							redirectTo('/pages/examPage/examInfo');
+						} else {
+							this.messageToggle('error', data.data.message)
+						}
 
-					} else {
-						this.messageToggle('error', data.data.message)
-					}
-					
-				})
+					})
+					.catch(err => {
+						this.messageToggle('error', "网络质量不佳,请重试")
+					})
 			}
 		},
 		mounted() {

+ 2 - 0
util/examStartUtil.js

@@ -0,0 +1,2 @@
+// 切屏监听启用禁止
+export const windowState = false;