The progress bar and the upper and lower questions switch, there are single choice, multiple choice, and fill in the blank

The progress bar and the upper and lower questions switch, there are single selection, multiple selection, and fill in the blanks. The result is similar to this. The writing is not good, just for reference, and the data is taken in the background

1. Components Li-examwidght

<template>
	<view>
		<view class="exam-item-testing">
			<view class="exam-item-inner" v-if='dataList.length > 0'>
				<view class="line_under exam-item-title">
					{
   
   {currentItem.questionName?currentItem.questionName:''}}
				</view>
				<!--  单选 -->
				<view v-show="currentItem.questionType==1" class="padding">
					<view class="exam-item-option" v-for="(item,rowIndex_1) in currentItem.list" v-bind:key='rowIndex_1'
					 @click="radioChange(item,rowIndex_1)">
					 <view class="color optionIcon" :class='{ active:rowIndex_1===currentCheck}'></view>
						<text>{
   
   {item}}</text>
					</view>
					
				</view>
				
				<!-- 多选 -->
				<checkbox-group class="padding" @change="checkboxChange"  v-show="currentItem.questionType==2">
					<view  v-for="(item,rowIndex_2) in currentItem.list" v-bind:key='rowIndex_2'>
						<view class="exam-item-option">
							<view class="color posi"  :class='{active:checkboxCheck(item)}'  :value="setCheckboxVal(rowIndex_2)">
							<checkbox class="check" style="opacity: 0;" :value="setCheckboxVal(item)" :checked="checkboxCheck(rowIndex_2)" /></view>
							<text>{
   
   {item}}</text>
						</view>
					</view>
				</checkbox-group>
				<!--  填空题 -->
				<view v-show="currentItem.questionType == 3">
					<view class="">
						<textarea class="textareas" @blur="bindTextAreaBlur" @input='bindTextinput' placeholder='请写下您的评论' :value='getTxtValue(currentIndex)' />
						</view>
				</view>
                <view class="taskNext">
                	<view  v-if="currentIndex == 0"  class="nor">{
   
   {lastText}}</view>
					<view  v-else-if="currentIndex != 0"  @tap="lastQuestion" class="nor">{
   
   {lastText}}</view>
                	<view v-show="currentIndex < dataList.length-1"   @tap="nextQuestion">{
   
   {nextText}}</view>
                </view>
				<view class="finish" v-show="currentIndex === dataList.length-1" >
					<view @tap="finish">{
   
   {finishText}}</view>
				</view>
			</view>
		</view>
		
		
	</view>
</template>

<script >
	export default {
		name: 'Li-ExamWidghtssss',
		props: {
			index: {
				info: Number,
				default: 0
			},
			dataList: {
				type: Array,
				default:function(){
					return [];
				}
			},
			finishText:{
				info: String,
				default: '提交'
			},
			lastText:{
				info: String,
				default: '上一题'
			},
			nextText:{
				info: String,
				default: '下一题'
			},
			
		
		},
		data() {
			return {
				number:0,
				windowHeight:500,
				showIndexBox:false,
				currentHasChange:false,
				currentIndex:0,
				currentItem:{}, //当前项
				currentCheck: undefined, //单选选定
				currentCheckBoxCheck: [] ,//多选选定
				currentText:""  ,//填空题
				showMask:false  ,//是否显示遮罩和题号
				indexboxAnimationData:[]  //题号区域动画
			};
		},
		watch: {
			index: function(val, oldVal) {
				this.currentIndex = val;
				this.currentSelectFinish(this.currentIndex);
				//console.log('new: %s, old: %s', val, oldVal)
			},
			dataList: function(val, oldVal) {
				this.currentItem = this.getCurrentItem();
			},
			numBoxShow: function(val, oldVal) {
				this.switchIndexBox();
			}
		},
		computed: {
		},
		created(){
			let that = this;
			uni.getSystemInfo({
			    success: function (res) {
					that.windowHeight = res.windowHeight;
					
			    }
			});
		},
		methods: {
			radioChange(item,index) {  //单选改变
			 // this.number= item.fldOptionIndex;
			 console.log(item,index)
				this.currentHasChange = true;
				this.currentCheck = index;
				this.dataList[this.currentIndex].fldAnswer = item;
				this.$emit('select', {
					question: this.getCurrentItem(),
					anwser: item
				});
			},
			checkboxChange(e) {  //多选改变
			console.log(e)
				this.currentHasChange = true;
				this.currentCheckBoxCheck = e.detail.value;
				this.dataList[this.currentIndex].fldAnswer = this.currentCheckBoxCheck.join(',');
				this.$emit('select', {
					question: this.getCurrentItem(),
					anwser: this.dataList[this.currentIndex].fldAnswer
				});
			},
			bindTextAreaBlur(e){  //填空结束
				// this.currentText = e.detail.value;
				// this.currentHasChange = true;
				// this.dataList[this.currentIndex].fldAnswer = this.currentText;
			},
			bindTextinput(e){  //填空值改变
				this.currentText = e.detail.value;
				this.currentHasChange = true;
				this.dataList[this.currentIndex].fldAnswer = this.currentText;
			},
			setCheckboxVal(val) {  //设置多选框的值,如果是数字,则转换成字符串
				if (typeof(val) == 'number')
					return val + "";
	
				return val;
			},
			checkboxCheck(num) { //检查多选框是否已经选定
				let that = this;
				for (let i = 0; i < that.currentCheckBoxCheck.length; i++)
					if (that.currentCheckBoxCheck[i] == num)
						return true;
	
				return false;
			},
			getTxtValue(currentIndex){
				return this.currentItem.fldAnswer?this.currentItem.fldAnswer:""
			},
			
			lastQuestion() {  //上一题
				let newIndex = this.currentIndex - 1;
				this.currentSelectFinish(newIndex);
			},
			nextQuestion() {  //下一题
				let newIndex = this.currentIndex + 1;
				this.currentSelectFinish(newIndex);
			},
			currentSelectFinish(newIndex){   //切换题目
				let that = this;
				let __oldIndex = that.currentIndex;
				let __newIndex = newIndex;
				if(!that.dataList[__oldIndex])
					return;
					
				
				
				if(that.dataList[__oldIndex].questionType ==1){
					that.$emit('selectFinish',
					{ 
						currentItem:{  //当前项
							question: that.dataList[__oldIndex],
							anwser: that.currentCheck,
							hasChange:that.currentHasChange,
							index:__oldIndex,
							total:that.dataList.length
						},
						newItem:{  //新项
							question: that.dataList[__newIndex],
							index:__newIndex,
							total:that.dataList.length
						}
					});
				}
				else if(that.dataList[__oldIndex].questionType == 2){
					that.$emit('selectFinish', 
					{
						currentItem:{  //当前项
							question: that.dataList[__oldIndex],
							anwser: that.currentCheckBoxCheck?that.currentCheckBoxCheck.join(','):'',
							hasChange:that.currentHasChange,
							index:__oldIndex,
							total:that.dataList.length,
						},
						newItem:{  //新项
							question: that.dataList[__newIndex],
							index:__newIndex,
							total:that.dataList.length
						}
					});
				}
				else if(that.dataList[__oldIndex].questionType == 3){
					that.$emit('selectFinish', 
					{
						currentItem:{  //当前项
							question: that.dataList[__oldIndex],
							anwser: that.currentText,
							hasChange:that.currentHasChange,
							index:__oldIndex,
							total:that.dataList.length,
						},
						newItem:{  //新项
							question: that.dataList[__newIndex],
							index:__newIndex,
							total:that.dataList.length
						}
					});
				}
				
				that.currentIndex = newIndex;
				that.currentItem = that.getCurrentItem();
				that.currentHasChange = false;
				
				that.checkQuestionSelected();
			},
			checkQuestionSelected(){  //初始化选择
				if(this.currentItem.questionType == 1){
					this.currentCheck = this.currentItem.fldAnswer;//单选选定
				}
				else if(this.currentItem.questionType == 2){
					this.currentCheckBoxCheck = this.currentItem.fldAnswer?this.currentItem.fldAnswer.split(','):[]; //多选选定
				}
				else if(this.currentItem.questionType == 3){
					this.currentText = this.currentItem.fldAnswer?this.currentItem.fldAnswer:[]; //填空
				}
			},
			finish(){  //全部选择完成
				this.$emit('finish', {
					questions: this.dataList
				});
			},
			getCurrentItem(){
				if(this.dataList.length == 0)
					return {};
				if(this.dataList[this.currentIndex])
					return this.dataList[this.currentIndex];
				else
					return {};
			},
			
			
		}
	}
</script>

<style lang="scss">
	page{
	}
	.exam-item-testing {
	}

	.exam-item-inner {
		margin-top: 57rpx;
	}

	.exam-item-title {
		padding: 0 20rpx;
		// border: 1px solid black;
		font-size: 36rpx;
		font-weight: bold;
	}
	.padding{
		padding: 0 20rpx;
	}
	.exam-item-option {
		/* border: 1rpx solid black; */
		display: flex;
		align-items: center;
		height: 77rpx;
		margin-top: 47rpx;
		border: 1rpx solid #F4F4F4;
		font-size: 36rpx;
		/* padding: 10rpx 0; */
	}
	.optionIcon{
		margin-right:27rpx;
		margin-left:27rpx;
		width: 20rpx !important;
		height: 20rpx !important; 
		border: 1rpx solid #AAAAAA;
		border-radius: 20rpx;
	}
	
	.exam-item-option textarea{
		border:1px solid gainsboro;
		border-radius: 10rpx;
		height:300rpx;
		width: 100%;
	}

	.exam-button-row {
		text-align: center;
	}
	
	.exam-indexbox{
		padding-bottom: 20rpx;
	}

	.exam-indexbox:before, .exam-indexbox:after{
		display: table;
		content: ' ';
	}
	.exam-indexbox:after{
		clear: both;
	}
	.exam-indexbox-item{
		text-align: center;
		vertical-align: middle;
		line-height: 56rpx;
		float: left;
		border:1rpx solid gainsboro;
		height: 56rpx;
		width: 56rpx;
		margin: 5rpx;
		padding: 10rpx;
		border-radius: 10rpx;
		background-color: #fff;
		-moz-box-shadow: 0px 1px 1px #ABABAB;
		-webkit-box-shadow: 0px 1px 1px #ABABAB;
		box-shadow: 0px 1px 1px #ABABAB;
	}
 
	.exam-indexbox-item-selected{
		color: #007AFF;
	}

	/* 以下为实现0.5px底部边界 */
	.line_under {
		// position: relative;
		/* .line_under:before{顶部top: 0;background: #000;} */
	}
	.line_under:before,
	.line_under:after {
		position: absolute;
		content: " ";
		height: 1px;
		width: 100%;
		left: 0;
		transform-origin: 0 0;
		-webkit-transform-origin: 0 0;
	}

	.line_under:after {
		bottom: 0;
		border-bottom: 1px solid gainsboro;
	}
	@media only screen and (-webkit-min-device-pixel-ratio: 1.5) {
		.line_under:after,
		.line_under:before {
			-webkit-transform: scaleY(0.667);
		}
	}
	@media only screen and (-webkit-min-device-pixel-ratio: 2) {
		.line_under:after,
		.line_under:before {
			-webkit-transform: scaleY(0.5);
		}
	}
	
	.exam-mask{
		position: absolute;
		z-index: 1;
		width: 100%;
		height: 100%;
		background-color: #999999;
		opacity:0.5;
		left: 0;
		top:0;
	}
	
	.exam-mask-content{
		position: absolute;
		z-index: 1;
		width: 100%;
		height: 50%;
		background-color: white;
		left: 0;
		bottom:0;
		padding: 15rpx 5rpx;
	}
	.exam-indexbox-item-mask{
		text-align: center;
		vertical-align: middle;
		line-height: 63rpx;
		float: left;
		border:1rpx solid gainsboro;
		height: 63rpx;
		width: 63rpx;
		margin: 5rpx;
		padding: 10rpx;
		border-radius: 10rpx;
		background-color: #fff;
		-moz-box-shadow: 0px 1px 1px #ABABAB;
		-webkit-box-shadow: 0px 1px 1px #ABABAB;
		box-shadow: 0px 1px 1px #ABABAB;
	}
	.taskNext{
		position: absolute;
		bottom: 0;
		left: 0;
		width: 100%;
		padding: 20rpx 0;
		height: 60rpx;
		background:linear-gradient(to left, #FE0000, #FF5033) ;
		display: flex;
		view{
			width: 50%;
			color: #FFFFFF;
			display: flex;
			align-items: center;
			justify-content: center;
			font-size: 36rpx;
		}
	}
	.nor{
		border-right: 1rpx solid #FFFFFF;
	}
	.finish{
		position: absolute;
		bottom: 0;
		left: 0;
		width: 100%;
		padding: 20rpx 0;
		height: 60rpx;
		background:linear-gradient(to left, #FE0000, #FF5033) ;
		color: #FFFFFF;
		display: flex;
		align-items: center;
		justify-content: center;
		font-size: 36rpx;
	}
	.textareas{
		border: 1px solid #F4F4F4;
		width: 99%;
		padding: 20rpx;
		margin-top: 27rpx;
	}
	.color{
		width: 20rpx !important;
		height: 20rpx !important; 
		border: 1rpx solid #AAAAAA;
		border-radius: 20rpx;
	}
	.active{
		background-color: #FE0000;
		border: 1rpx solid #FE0000;
	}
    .posi{
		z-index:44 ;
		position: relative;
		margin-left: 26rpx;
		margin-right: 26rpx;
	}
    .check{
		border: 1px solid black;
		top: -20rpx;
		left: -2rpx;
		position: absolute;
	}
</style>

2. Progress bar component

<template>
	<view>
		<view class="uni-progress-box">
			<view class="progress-bottom"><view class="progress" :style="{ width: percentage + '%', background: percentBackground }"></view></view>
		</view>
	</view>
</template>

<script>
export default {
	props: {
		// 进度条占比
		percentage: {
			type: Number,
			default: 0
		},
		// 进度条占比的颜色设置
		percentBackground: {
			type: String,
			default: null
		}
	}
};
</script>

<style lang="scss">
.uni-progress-box {
	width:100%;
	display: flex;
	.progress-bottom {
		margin-top: 20rpx;
		height: 16rpx;
		width: 100%;
		background-color:#CCCCCC;
		border-radius: 20rpx;
		.progress {
			width: 100%;
			height: 16rpx;
			border-radius: 20rpx;
		}
	}
	.percentage {
		margin: 0 4%;
	}
}
</style>

3. Page

<template>
	<view>
		<view class="taskProgess">
			<view class="taskNum">
				<label class="nowNum">{
   
   { nowNum }}</label>
				/
				<label>{
   
   { totals }}</label>
			</view>
			<view style="width: 100%;"><uniProgress :percentage="shortPro" percentBackground="#FE0000"></uniProgress></view>
		</view>
		<view class="taskTit">已完成{
   
   { nowNum }}个,还差{
   
   { shortNum }}个可领取积分</view>
		<exam-widght
			:dataList="QuestionList"
			:index="index"
			@select="selectItem"
			@selectFinish="selectFinish"
			@finish="finish"
			:numBoxType="0"
			:showIndexText="showIndexText"
			:numBoxShow="numBoxShow"
		></exam-widght>
	</view>
</template>

<script>
import uniProgress from '@/components/uni-progress.vue';
import examWidght from '@/components/Li-ExamWidght/Li-ExamWidght.vue';
import { mapGetters } from 'vuex';
var _this;
export default {
	components: {
		examWidght,
		uniProgress
	},
	data() {
		return {
			totals: 10,
			shortPro: 10,
			shortNum: 10,
			nowNum: 1,
			fldTestPaperID: undefined,
			fldTestRecordID: undefined,
			showIndexText: true, //题号文字是否显示
			numBoxShow: false,
			items: [],
			index: 0,
			QuestionList: [],
			radio: '1',
			allAnswer:[],
			all:'',
			id:0,
			
		};
	},
	onLoad(params) {
		this.id=parseInt(params.id)
		this.init(params);
		console.log(111);
		_this = this;
		setTimeout(function() {
			_this.getTestPaper();
		}, 1000);
	},
	computed: {
		...mapGetters({
			taskContent: 'task/GetTaskContent'
		}),
		questlist() {
			let arr = [];
			if (this.taskContent != '') {
				for (var index in this.taskContent) {
					var item = this.taskContent[index];
					arr.push(item);
				}
				return arr;
			} else {
				return arr;
			}
		},
		
	},
	methods: {
		init(params) {
			const reportId = {
				reportId: params.reportId
			};
			this.$store.dispatch('task/getTaskContent', reportId);
		},
		check(index) {
			// 先取消所有选中项
			this.radios.forEach(item => {
				item.isChecked = false;
			});
			//再设置当前点击项选中
			this.radio = this.radios[index].value;
			// 设置值,以供传递
			this.radios[index].isChecked = true;
			console.log(this.radio);
		},
		jump() {
			this.index = 9;
		},
		switchIndexBox() {
			this.numBoxShow = !this.numBoxShow;
		},
		//提交
		finish(item) {
			let items=item
			if(items.questions!=null){
				for (var index in items.questions) {
					var answera = items.questions[index].fldAnswer;
					this.allAnswer.push(answera);
				}
				this.all=this.allAnswer
				console.log(this.all)
			}
			const paramess={
				poolId:this.id,
				answer:this.all
			}
			this.$store.dispatch('task/getTaskSubmits',paramess);
			// uni.showToast({
			// 	title:'提交成功',
				
			// })
			uni.switchTab({
				url:'taskSucess'
			})
		},
		selectItem(item) {
			console.log('selectItem');
		},
		selectFinish(item) {
			console.log('selectFinish');
			// console.log('3' + JSON.stringify(item));
			
			let index = item.newItem.index + 1;
			let title = index + '/' + item.newItem.total;
			this.nowNum = index;
			if (this.nowNum == 1) {
				this.shortPro = 10;
			} else if (this.nowNum == 2) {
				this.shortPro = 20;
			} else if (this.nowNum == 3) {
				this.shortPro = 30;
			} else if (this.nowNum == 4) {
				this.shortPro = 40;
			} else if (this.nowNum == 5) {
				this.shortPro = 50;
			} else if (this.nowNum == 6) {
				this.shortPro = 60;
			} else if (this.nowNum == 7) {
				this.shortPro = 70;
			} else if (this.nowNum == 8) {
				this.shortPro = 80;
			} else if (this.nowNum == 9) {
				this.shortPro = 90;
			} else if (this.nowNum == 10) {
				this.shortPro = 100;
			}
			this.shortNum = this.totals - this.nowNum;
		},
		getTestPaper() {
			console.log(_this.questlist)
			_this.QuestionList = _this.questlist;
			
		}  
	}
};
</script>

<style lang="scss">
page {
	position: relative;
	height: 100%;
	overflow-x: hidden;
}
.taskProgess {
	// border: 1px solid black;
	display: flex;
	flex-shrink: 1;
	align-content: center;
	padding: 20rpx;
	font-size: 30rpx;
	.taskNum {
		margin-right: 34rpx;
		.nowNum {
			font-size: 36rpx;
		}
	}
}
.taskTit {
	color: #fe0000;
	font-size: 20rpx;
	display: flex;
	align-items: center;
	justify-content: center;
	margin-top: 3rpx;
}
.taskContent {
	// border: 1px solid black;
	margin-top: 55rpx;
	padding: 0 20rpx;
	.itemTitle {
		color: #212121;
		font-size: 36rpx;
		font-weight: bold;
		flex-wrap: wrap;
		margin-bottom: 47rpx;
	}
	.radioTitle {
		// border: 1px solid black;
		.radio-box {
			border: 1rpx solid #f4f4f4;
			display: flex;
			align-items: center;
			height: 77rpx;
			margin-bottom: 32rpx;
		}
		.radio {
			border: 1rpx solid #aaaaaa;
			display: inline-block;
			width: 20rpx;
			height: 20rpx;
			vertical-align: middle;
			cursor: pointer;
			border-radius: 10rpx;
			margin-left: 27px;
			margin-right: 27px;
		}
		.input-radio {
			border-radius: 10rpx;
			position: absolute;
			opacity: 0;
			width: 20px;
			height: 20px;
			cursor: pointer;
			left: 0px;
			outline: none;
			-webkit-appearance: none;
		}
		.on {
			border: 1rpx solid #fe0000;
			background-color: #fe0000;
		}
	}
}
.taskNext {
	position: absolute;
	bottom: 0;
	left: 0;
	width: 100%;
	padding: 20rpx 0;
	height: 60rpx;
	background: linear-gradient(to left, #fe0000, #ff5033);
	display: flex;
	view {
		width: 50%;
		color: #ffffff;
		display: flex;
		align-items: center;
		justify-content: center;
		font-size: 36rpx;
	}
	.nor {
		border-right: 1rpx solid #ffffff;
	}
}
</style>

 

Guess you like

Origin blog.csdn.net/qq706352062/article/details/103433424