| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556 | <template>	<view class="phone-kaoshi-page">		<!-- 导航区域 -->		<view class="icon-title-bjcolor-navBar-box">			<view @click="handleBack" class="nav-bar-icon"></view>			<text class="nav-bar-title">{{data.lxName}}</text>		</view>		<!-- 第一行 -->		<view class="kaoshi-page-title">			<!--  倒计时 -->			<view v-if="!!data.endSecond">				<text>考试倒计时:</text>				<uni-countdown :show-day="true" :second="1000" @timeup="onTimeUp"					:start="startCountDown"></uni-countdown>			</view>			<view v-if="activeSt" class="title-types">{{dlName}}</view>		</view>		<view class="kaoshi-shiti-content">			<!-- 内容区域 -->			<!-- 试题区域 -->			<view v-if="activeSt">				<template v-if="activeSt.stTypeId == 1">					<!-- 单选 -->					<danxuan :question="activeSt" :key="activeSt.stId"></danxuan>				</template>				<template v-if="activeSt.stTypeId == 2">					<!-- 多选 -->					<duoxuan :question="activeSt" :key="activeSt.stId"></duoxuan>				</template>				<template v-if="activeSt.stTypeId == 3">					<!-- 判断 -->					<panduan :question="activeSt" :key="activeSt.stId"></panduan>				</template>				<template v-if="activeSt.stTypeId == 4">					<!-- 填空 -->					<tiankong :question="activeSt" :key="activeSt.stId"></tiankong>				</template>			</view>		</view>		<view class="kaoshi-bottom-box">			<button class="phone-green-btn bj-btn" hover-class="none" type="default" size="mini"				@click="handleBiaoji">{{activeSt && activeSt.marked ? '取标':'标记'}}</button>			<view @click="showAnswerCard" class="shiti-num-box">				<icon class="shiti-num-icon"></icon>				<text					class="active-num">{{activeSt ? activeSt.onlyNum: 0}}</text>/<text>{{data.StListForSearch.length}}</text>			</view>		</view>		<template v-if="activeSt">			<button type="default" size="mini" hover-class="none" class="phone-green-btn ks-btn-prev"				@click="handlePrev" v-if="!isFistStId">上一题</button>			<button type="default" size="mini" hover-class="none" class="phone-green-btn ks-btn-next"				@click="handleNext" v-if="!isLastStId">下一题</button>			<button type="default" size="mini" hover-class="none" class="phone-green-btn ks-btn-next"				@click="handleJiaojuan" v-if="isLastStId">交卷</button>		</template>		<!-- 答题卡 -->		<uni-popup ref="popupRef" background-color="#fff" :is-mask-click="false" :mask-click="false">			<view class="answer-card-popup">				<view class="icon-title-bjcolor-navBar-box">					<view @click="handlePopupBack" class="nav-bar-icon"> </view>					<text class="nav-bar-title">答题卡</text>				</view>				<view class="answer-card-content" v-for="(paragraph,paragraphIndex) in questionData"					:key="paragraphIndex">					<view class="paragraph-title">						{{paragraph.name}}					</view>					<view class="paragraph-qa" v-for="(qa,qaIndex) in paragraph.qas" :key="qaIndex"						:class="getQaClass(qa)" @click="answerCardItemClick(qa)">{{qa.onlyNum}}					</view>				</view>			</view>		</uni-popup>		<!-- 交卷确认 -->		<answerQueren ref="answerQrRef" @confirm="handleQuerenConfirm"></answerQueren>		<!-- 考试得分 -->		<submitScoreVue title="练习得分" nameKey="lxName" ref="subScoreRef" labelName="练习总分" @confirm="handleScoreConfirm" @close="handleScoreClose"></submitScoreVue>	</view></template><script setup>	import {		ref,		reactive,		computed,		watch,		nextTick	} from "vue";	import answerQueren from "@/components/zhuapaiConfirm/answerQueren.vue";	import submitScoreVue from "@/components/zhuapaiConfirm/submitScore.vue";	import {		onLoad	} from "@dcloudio/uni-app";	import * as lxApi from "@/api/lianxi.js"	import danxuan from "@/components/questions/danxuan.vue";	import duoxuan from "@/components/questions/duoxuan.vue";	import tiankong from "@/components/questions/tiankong.vue";	import panduan from "@/components/questions/panduan.vue";	import {		useQuestionTools	} from "@/components/questions/useQuestionTools.js";	const {		checkDanxuanReply,		checkDuoxuanReply,		checkPanduanReply,		checkTiankongReply,		getLetterByIndex	} = useQuestionTools();	onLoad((option) => {		data.lxId = option.lxId;		data.zhuapai = option.zhuapai;		data.from = option.from;		initKaoshi();	})	const popupRef = ref(null)	const zhuapaiConfirmRef = ref(null)	const answerQrRef = ref(null);	const startCountDown = ref(false);	const subScoreRef = ref(null)		const timer1 = ref(null);	const data = reactive({		lxId: null,		operId: null,		lxName: '',		stTotal: 0,		stScore: 0,		biaoji: {},		endSecond: 0,		pageSize: 0,		toggleScreenFlag: 0,		toggleScreenSecond: 0,		zhuapai: 0,		duanluo: [],		StListForSearch: [],		from: '',		hisId: null	})		const markDB = ref([]);	const questionData = ref([]);	const progress = reactive({		dlIndex: 0,		dtIndex: 0	})	const dlName = computed(() => {		if (data.StListForSearch && activeSt.value) {			return data.StListForSearch[activeSt.value.onlyNum - 1].paragraphName		} else {			return ''		}	})	watch(() => data.duanluo, (newVal) => {		// 计算已答试题数量	}, {		deep: true	})	const activeSt = computed(() => {		if (questionData.value.length) {			return questionData.value.length && questionData.value[progress.dlIndex].qas[progress.dtIndex];		} else {			return null		}	})	const isFistStId = computed(() => {		if (data.StListForSearch.length) {			return data.StListForSearch[0].stId == activeSt.value.stId		} else {			return false		}	});	const isLastStId = computed(() => {		if (data.StListForSearch.length) {			return data.StListForSearch[data.StListForSearch.length - 1].stId == activeSt.value.stId		} else {			return false		}	});			function handleScoreClose() {				handleBack()	}		// 考试得分相关 start	function handleScoreConfirm() {		uni.redirectTo({			url: `/pages/client/Chengji/lxScoreShijuan?hisId=${data.hisId}&from=lianxi`		})	}		// 考试得分相关 end		//  交卷相关功能 start	function checkJiaojuan() {		const result = []		let count = 0;		let total = 0;		questionData.value.forEach(dl => {			dl.qas.forEach(st => {				const opt = {					stId: st.stId,					reply: st.reply,					stTypeId: st.stTypeId				}				result.push(opt)			})		})		result.forEach(item => {			total++;			if (item.stTypeId == 1 && !checkDanxuanReply(item)) {				count++;			}			if (item.stTypeId == 2 && !checkDuoxuanReply(item)) {				count++;			}			if (item.stTypeId == 3 && !checkPanduanReply(item)) {				count++;			}			if (item.stTypeId == 4 && !checkTiankongReply(item)) {				count++;			}		})		return {			total,			count,		}	}	function handleJiaojuan() {		const result = checkJiaojuan()		console.log(result)		if (result.count) {			// 提示			answerQrRef.value.showDialog({				answercartsCount: result.total - result.count,				answercartsTotal: result.total,			})		} else {			handleSubmit()		}	}	function handleQuerenConfirm() {		handleSubmit()	}		function handleSubmit(force = false) {		const result = {			force,			operId: data.operId,			replyList: []		};		questionData.value.forEach(dl => {			dl.qas.forEach(st => {				const opt = {					stId: st.stId,					reply: st.reply				}				result.replyList.push(opt)			})		})				uni.showLoading({			title: '提交中'		})			lxApi.getClientLianxiSubmit(result).then(res => {			if (res.code == 0) {				data.hisId = res.data.hisId;				subScoreRef.value.showDialog(res.data);			}		}).finally(() => {			uni.hideLoading()		})	}		function onTimeUp() {		handleSubmit(true);	}	//  交卷相关功能 end	function forceSubmit() {		// 强制交卷		console.log('强制交卷')		handleSubmit(true)	}	function getQaClass(qa) {		if (qa.marked && qa.marked === true) {			return 'paragraph-qa-block-mark';		} else {			if (qa.stTypeId == 1) {				if (checkDanxuanReply(qa)) {					return 'paragraph-qa-block-done';				} else {					return 'paragraph-qa-block-init';				}			} else if (qa.stTypeId == 2) {				if (checkDuoxuanReply(qa)) {					return 'paragraph-qa-block-done';				} else {					return 'paragraph-qa-block-init';				}			} else if (qa.stTypeId == 3) {				if (checkPanduanReply(qa)) {					return 'paragraph-qa-block-done';				} else {					return 'paragraph-qa-block-init';				}			} else if (qa.stTypeId == 4) {				if (checkTiankongReply(qa)) {					return 'paragraph-qa-block-done';				} else {					return 'paragraph-qa-block-init';				}			}		}	}	function skipQuestion(dlIndex, dtIndex) {		progress.dlIndex = dlIndex;		progress.dtIndex = dtIndex;		handlePopupBack()	}	function answerCardItemClick(qa) {		const actQa = data.StListForSearch.find(item => item.stId == qa.stId);		skipQuestion(actQa.dlIndex, actQa.dtIndex)	}	function handleBack() {		const pages = getCurrentPages();		if (pages.length>1) {			uni.navigateBack()		} else {			/* if (data.from == 'shouye') {				uni.redirectTo({					url: '/pages/client/ShouYe/shouye'				})			} else if (data.from == 'lianxiList') {				uni.redirectTo({					url: '/pages/client/Lianxi/list'				})			} else {				uni.redirectTo({					url: "/pages/client/ShouYe/shouye"				})			} */			 history.back();		}			}	function showAnswerCard() {		popupRef.value.open('bottom')	}	function handlePopupBack() {		popupRef.value.close()	}	function handlePrev() {		const qa = data.StListForSearch.find(item => item.stId == activeSt.value.stId);		const index = qa.onlyNum - 1;		if (index > 0) {			const result = data.StListForSearch[index - 1];			progress.dlIndex = result.dlIndex;			progress.dtIndex = result.dtIndex		}	}	function handleNext() {		const qa = data.StListForSearch.find(item => item.stId == activeSt.value.stId);		const index = qa.onlyNum - 1;		if (index < data.StListForSearch.length) {			const result = data.StListForSearch[index + 1];			progress.dlIndex = result.dlIndex;			progress.dtIndex = result.dtIndex		}	}	function formatDuanluoList(dlData) {		let uIndex = 0; // 试题onlyNum		let iDuanluo = 0; // 段落onlyNum		let result = [];		for (const duanluo of data.duanluo) {			let paragraph = {				qas: [],			};			paragraph.name = duanluo.name;			let iQa = 0; // 当前试题序号			let order = 0; // 当前题型中第几题			for (const iDanxuan of duanluo.danxuan) {				iDanxuan.type = 'danxuan';				iDanxuan.marked = data.biaoji[iDanxuan.stId] ? true: false;				iDanxuan.onlyNum = uIndex + 1;				iDanxuan.order = order;				iDanxuan.iQa = iQa;				paragraph.qas.push(iDanxuan);				uIndex++;				order++;				iQa++;				data.StListForSearch.push({					stId: iDanxuan.stId,					paragraphName: paragraph.name,					dlIndex: iDuanluo,					dtIndex: iDanxuan.iQa,					onlyNum: iDanxuan.onlyNum				})			}			order = 0;			for (const iDuoxuan of duanluo.duoxuan) {				iDuoxuan.type = 'duoxuan';				iDuoxuan.marked = data.biaoji[iDuoxuan.stId] ? true: false;				iDuoxuan.onlyNum = uIndex + 1;				iDuoxuan.order = order;				paragraph.qas.push(iDuoxuan);				iDuoxuan.iQa = iQa;				iDuoxuan.reply = [];				uIndex++;				order++;				iQa++;				data.StListForSearch.push({					stId: iDuoxuan.stId,					paragraphName: paragraph.name,					dlIndex: iDuanluo,					dtIndex: iDuoxuan.iQa,					onlyNum: iDuoxuan.onlyNum				})			}			order = 0;			for (const iPanduan of duanluo.panduan) {				iPanduan.type = 'panduan';				iPanduan.marked = data.biaoji[iPanduan.stId] ? true: false;				iPanduan.onlyNum = uIndex + 1;				iPanduan.order = order;				paragraph.qas.push(iPanduan);				iPanduan.iQa = iQa;				uIndex++;				order++;				iQa++;				data.StListForSearch.push({					stId: iPanduan.stId,					paragraphName: paragraph.name,					dlIndex: iDuanluo,					dtIndex: iPanduan.iQa,					onlyNum: iPanduan.onlyNum				})			}			order = 0;			for (const iTiankong of duanluo.tiankong) {				iTiankong.type = 'tiankong';				iTiankong.marked = data.biaoji[iTiankong.stId] ? true: false;				iTiankong.onlyNum = uIndex + 1;				iTiankong.order = order;				paragraph.qas.push(iTiankong);				iTiankong.iQa = iQa;				iTiankong.reply = new Array(iTiankong.count).fill('');;				uIndex++;				order++;				iQa++;				data.StListForSearch.push({					stId: iTiankong.stId,					paragraphName: paragraph.name,					dlIndex: iDuanluo,					dtIndex: iTiankong.iQa,					onlyNum: iTiankong.onlyNum				})			}			iDuanluo++;			questionData.value.push(paragraph)			console.log('1', questionData.value)			console.log('2', data.StListForSearch)		}	}	function handleBiaoji() {		activeSt.value.marked = !activeSt.value.marked;		data.biaoji.value[activeSt.value.stId] = activeSt.value.marked		lxApi.getClientLianxiBiaoji({			operId: data.operId,			biaoji: JSON.stringify(data.biaoji)		}).catch(err => {			uni.redirectTo({				url: '/pages/client/Lianxi/list'			})		})	}	function initKaoshi() {		lxApi.getClientLianxiStart({			lxId: data.lxId		}).then(res => {			const {				lxId,				operId,				lxName,				stTotal,				stScore,				biaoji,				endSecond,				pageSize,				toggleScreenFlag,				toggleScreenSecond,				zhuapai,				duanluoList			} = res.data;			data.lxId = lxId;			data.operId = operId;			data.lxName = lxName;			data.stTotal = stTotal;			data.stScore = stScore;			data.biaoji = biaoji ? JSON.parse(biaoji): {};			data.endSecond = endSecond;			data.pageSize = pageSize;			data.duanluo = duanluoList;			formatDuanluoList(data.duanluo);			uni.setNavigationBarTitle({				title: data.lxName			});			startCountDown.value = true;		}).catch(err => {      handleBack()    })	}</script>
 |