refactor(train_management): 优化签名展示和签到状态显示逻辑- 在 exam_record.vue 中将签字图片展示方式从 u-image 改为 image 组件
- 在 sign_information.vue 中完善签到状态和考试签到状态的显示逻辑- 更新 BusStagestudentrelationDao.xml 中的排序逻辑,根据状态和创建时间排序hyx_2025-01-13_xgf2.0
							parent
							
								
									aee7e4332b
								
							
						
					
					
						commit
						bd40af6eb3
					
				|  | @ -8,3 +8,4 @@ export const uploadFile = (params) => upload("/app/sys/file/uploadFile", params) | |||
| export const setRefreshToken = (params) => post("/sys/refreshToken", params ); // 刷新token
 | ||||
| export const setEntryV1 = (params) => post("/app/sys/user/entry", params ); // 入职
 | ||||
| export const resignV1 = (params) => post("/app/sys/user/resign", params ); // 离职
 | ||||
| export const getStudentInfoApi = (params) => post("/app/student/getStudentInfo", params ); // 获取学员信息
 | ||||
|  |  | |||
|  | @ -128,6 +128,33 @@ export default { | |||
| 								CODE_TYPE: obj[0].CODE_TYPE | ||||
| 							} | ||||
| 						}) | ||||
| 					} else if (type === '2') { | ||||
| 						// 签到二维码方式进入, [type: 2 --> 签到二维码方式进入] | ||||
| 						if (findClassId) { | ||||
| 							uni.$u.route({ | ||||
| 								url: '/pages/train_management/realname_info_auth', | ||||
| 								params: { | ||||
| 									type: 'scan_face', | ||||
| 									classId | ||||
| 								} | ||||
| 							}) | ||||
| 						} else { | ||||
| 							uni.$u.toast('您未在培训计划内,无法入班签到,请联系教师') | ||||
| 						} | ||||
| 					} else if (type === '3') { | ||||
| 						// 考试二维码方式进入 [type: 3 --> 考试二维码方式进入] | ||||
| 						if (findClassId) { | ||||
| 							uni.$u.route({ | ||||
| 								url: '/pages/train_management/face_authentication', | ||||
| 								params: { | ||||
| 									type: 'learning_certification', | ||||
| 									stageexampaperinputId, | ||||
| 									classId, | ||||
| 								} | ||||
| 							}) | ||||
| 						} else { | ||||
| 							uni.$u.toast('您未在培训计划内,无法进行考试,请联系教师') | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 			}) | ||||
|  |  | |||
|  | @ -7,15 +7,17 @@ | |||
| 		</view> | ||||
| 
 | ||||
| 		<view class="content__info"> | ||||
| 			<view>姓名: {{info.username}}</view> | ||||
| 			<view>分数: {{info.examscore}}分</view> | ||||
| 			<view class="content__top"> | ||||
| 				<view>姓名: {{info.username}}</view> | ||||
| 				<view>分数: {{info.examscore}}分</view> | ||||
| 			</view> | ||||
| 			<view>考试时间: {{info.examtimeend}}</view> | ||||
| 		</view> | ||||
| 
 | ||||
| 		<view class="content__sign"> | ||||
| 			<view style="margin-right: 10rpx">签字: </view> | ||||
| 			<image style="width: 120rpx; height: 70rpx;" :src="$filePath + info.signaturePath" /> | ||||
|     </view> | ||||
| 		</view> | ||||
| 
 | ||||
| 		<view class="counter"> | ||||
| 			当前试题: <text style="color: orange">{{ current + 1 }}</text>/{{ questionList.length }} | ||||
|  | @ -30,7 +32,8 @@ | |||
| 				<text>{{ questionList[current].questiondry }}</text> | ||||
| 			</view> | ||||
| 			<view v-if="questionList[current].questiontype === '1'" class="options"> | ||||
| 				<view v-for="(item, index) in ['A', 'B', 'C', 'D']" :key="index" :class="['item', questionList[current].answer === item ? 'active' : '']"> | ||||
| 				<view v-for="(item, index) in ['A', 'B', 'C', 'D']" :key="index" | ||||
| 					:class="['item', questionList[current].answer === item ? 'active' : '']"> | ||||
| 					<text class="option">{{ item }}</text> | ||||
| 					<text class="text"> | ||||
| 						{{ questionList[current]['option' + item.toLocaleLowerCase()] }} | ||||
|  | @ -38,7 +41,8 @@ | |||
| 				</view> | ||||
| 			</view> | ||||
| 			<view v-if="questionList[current].questiontype === '2'" class="options"> | ||||
| 				<view v-for="(item, index) in ['A', 'B', 'C', 'D']" :key="index" :class="['item', questionList[current].answer && questionList[current].answer.indexOf(item) !== -1 ? 'active' : '']"> | ||||
| 				<view v-for="(item, index) in ['A', 'B', 'C', 'D']" :key="index" | ||||
| 					:class="['item', questionList[current].answer && questionList[current].answer.indexOf(item) !== -1 ? 'active' : '']"> | ||||
| 					<text class="option">{{ item }}</text> | ||||
| 					<text class="text"> | ||||
| 						{{ questionList[current]['option' + item.toLocaleLowerCase()] }} | ||||
|  | @ -46,7 +50,8 @@ | |||
| 				</view> | ||||
| 			</view> | ||||
| 			<view v-if="questionList[current].questiontype === '3'" class="options"> | ||||
| 				<view v-for="(item, index) in ['A', 'B']" :key="index" :class="['item', questionList[current].answer === item ? 'active' : '']"> | ||||
| 				<view v-for="(item, index) in ['A', 'B']" :key="index" | ||||
| 					:class="['item', questionList[current].answer === item ? 'active' : '']"> | ||||
| 					<text class="option"> | ||||
| 						{{ questionList[current]['option' + item.toLocaleLowerCase()] }} | ||||
| 					</text> | ||||
|  | @ -59,8 +64,8 @@ | |||
| 					{{ questionList[current].answerright === 'A' ? '对' : '错' }} | ||||
| 				</view> | ||||
| 				<view v-else>{{ questionList[current].answerright || '无' }}</view> | ||||
|         <text>权威解读</text> | ||||
|         <view>{{ questionList[current].descr || "无" }}</view> | ||||
| 				<text>权威解读</text> | ||||
| 				<view>{{ questionList[current].descr || "无" }}</view> | ||||
| 			</view> | ||||
| 		</view> | ||||
| 
 | ||||
|  | @ -92,184 +97,194 @@ | |||
| </template> | ||||
| 
 | ||||
| <script> | ||||
| import { getTaskScoreInfo } from "@/api"; | ||||
| 	import { | ||||
| 		getTaskScoreInfo | ||||
| 	} from "@/api"; | ||||
| 
 | ||||
| export default { | ||||
| 	data() { | ||||
| 		return { | ||||
|       info:{}, | ||||
| 			questionList: [], | ||||
| 			current: 0, // 新增当前激活的题目索引 | ||||
| 			questionTypeMap: { | ||||
| 				1: '单选题', | ||||
| 				2: '多选题', | ||||
| 				3: '判断题', | ||||
| 				4: '填空题', | ||||
| 				5: '简答题' | ||||
| 	export default { | ||||
| 		data() { | ||||
| 			return { | ||||
| 				info: {}, | ||||
| 				questionList: [], | ||||
| 				current: 0, // 新增当前激活的题目索引 | ||||
| 				questionTypeMap: { | ||||
| 					1: '单选题', | ||||
| 					2: '多选题', | ||||
| 					3: '判断题', | ||||
| 					4: '填空题', | ||||
| 					5: '简答题' | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	}, | ||||
| 		}, | ||||
| 
 | ||||
| 	onLoad(query) { | ||||
| 		const { stagestudentrelationId, classId } = query | ||||
| 		this.getData(stagestudentrelationId, classId) | ||||
| 	}, | ||||
| 
 | ||||
| 	mounted() {}, | ||||
| 
 | ||||
| 	methods: { | ||||
| 		async getData(stagestudentrelationId, classId) { | ||||
| 			const resData = await getTaskScoreInfo({ | ||||
| 		onLoad(query) { | ||||
| 			const { | ||||
| 				stagestudentrelationId, | ||||
| 				classId | ||||
| 			}) | ||||
| 			this.questionList = resData.pd.questionList | ||||
| 			this.info = resData.pd | ||||
| 			console.log(this.info) | ||||
| 			} = query | ||||
| 			this.getData(stagestudentrelationId, classId) | ||||
| 		}, | ||||
| 		handleCalcQuestType(type) { | ||||
| 			return `(${this.questionTypeMap[type]})` | ||||
| 		}, | ||||
|     previewImage(){ | ||||
|       uni.previewImage({ | ||||
|         urls: [this.$filePath + this.info.signaturePath], | ||||
|       }) | ||||
|     } | ||||
| 
 | ||||
| 		mounted() {}, | ||||
| 
 | ||||
| 		methods: { | ||||
| 			async getData(stagestudentrelationId, classId) { | ||||
| 				const resData = await getTaskScoreInfo({ | ||||
| 					stagestudentrelationId, | ||||
| 					classId | ||||
| 				}) | ||||
| 				this.questionList = resData.pd.questionList | ||||
| 				this.info = resData.pd | ||||
| 				console.log(this.info) | ||||
| 			}, | ||||
| 			handleCalcQuestType(type) { | ||||
| 				return `(${this.questionTypeMap[type]})` | ||||
| 			}, | ||||
| 			previewImage() { | ||||
| 				uni.previewImage({ | ||||
| 					urls: [this.$filePath + this.info.signaturePath], | ||||
| 				}) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| </script> | ||||
| 
 | ||||
| <style scoped lang="scss"> | ||||
| .content { | ||||
| 	padding: 16rpx; | ||||
| 	.content { | ||||
| 		padding: 16rpx; | ||||
| 
 | ||||
| 	.content__titletop { | ||||
| 		text-align: center; | ||||
| 		.content__titletop { | ||||
| 			text-align: center; | ||||
| 
 | ||||
| 		.content__title { | ||||
| 			.content__title { | ||||
| 				font-size: 34rpx; | ||||
| 				font-weight: 600; | ||||
| 			} | ||||
| 
 | ||||
| 			.content__subtitle { | ||||
| 				margin-top: 8rpx; | ||||
| 				font-size: 24rpx; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		.content__info { | ||||
| 			font-size: 34rpx; | ||||
| 			font-weight: 600; | ||||
| 		} | ||||
| 
 | ||||
| 		.content__subtitle { | ||||
| 			margin-top: 8rpx; | ||||
| 			font-size: 24rpx; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	.content__info { | ||||
| 		font-size: 34rpx; | ||||
|     view{ | ||||
|       margin-top: 18rpx; | ||||
|     } | ||||
| 	} | ||||
| 
 | ||||
| 	.content__sign { | ||||
| 		margin-top: 18rpx; | ||||
| 		font-size: 34rpx; | ||||
| 		display: flex; | ||||
| 		align-items: center; | ||||
| 	} | ||||
| 
 | ||||
| 	.counter { | ||||
| 		font-size: 28rpx; | ||||
| 		margin: 15rpx 0; | ||||
| 		text-align: end; | ||||
| 	} | ||||
| 
 | ||||
| 	.topic { | ||||
| 		box-sizing: border-box; | ||||
| 
 | ||||
| 		.tag_title { | ||||
| 			font-size: 28rpx; | ||||
| 			background-color: #fff; | ||||
| 			color: #5ac725; | ||||
| 			border-radius: 8rpx; | ||||
| 			padding: 2rpx 8rpx; | ||||
| 			margin-right: 10rpx; | ||||
| 		} | ||||
| 
 | ||||
| 		.title { | ||||
| 			font-size: 32rpx; | ||||
| 			font-weight: 600; | ||||
| 
 | ||||
| 			.question-type { | ||||
| 				border-radius: 40rpx; | ||||
| 				padding: 4rpx 14rpx; | ||||
| 				border: 1rpx solid #3c9cff; | ||||
| 				font-size: 28rpx; | ||||
| 				color: #3c9cff; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		.options { | ||||
| 			margin-top: 40rpx; | ||||
| 
 | ||||
| 			.item { | ||||
| 				position: relative; | ||||
| 				margin-top: 40rpx; | ||||
| 				color: #696868; | ||||
| 
 | ||||
| 				&.active { | ||||
| 					color: #3c9cff; | ||||
| 
 | ||||
| 					.option { | ||||
| 						background-color: #3c9cff; | ||||
| 						color: #fff; | ||||
| 					} | ||||
| 				} | ||||
| 
 | ||||
| 				.option { | ||||
| 					background-color: #eee; | ||||
| 					border-radius: 80rpx; | ||||
| 					width: 65rpx; | ||||
| 					height: 65rpx; | ||||
| 					line-height: 65rpx; | ||||
| 					text-align: center; | ||||
| 					font-size: 30rpx; | ||||
| 					display: inline-block; | ||||
| 				} | ||||
| 
 | ||||
| 				.text { | ||||
| 					margin-left: 30rpx; | ||||
| 					height: 60rpx; | ||||
| 					line-height: 60rpx; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		.correct-answer { | ||||
| 			margin-top: 40rpx; | ||||
| 
 | ||||
| 			text { | ||||
| 				display: inline-block; | ||||
| 				margin-top: 40rpx; | ||||
| 				color: #696868; | ||||
| 				font-size: 30rpx; | ||||
| 				font-weight: bold; | ||||
| 			} | ||||
| 
 | ||||
| 			view { | ||||
| 				margin-top: 20rpx; | ||||
| 				color: #333; | ||||
| 				padding: 20rpx; | ||||
| 				background-color: #eee; | ||||
| 				border-radius: 10rpx; | ||||
| 				font-size: 30rpx; | ||||
| 				margin-top: 8rpx; | ||||
| 			} | ||||
| 			 | ||||
| 			.content__top { | ||||
| 				display: flex; | ||||
| 				align-items: center; | ||||
| 				justify-content: space-between; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	.footer { | ||||
| 		position: fixed; | ||||
| 		bottom: 0; | ||||
| 		width: 100%; | ||||
| 		left: 0; | ||||
| 		padding: 20rpx; | ||||
| 		box-sizing: border-box; | ||||
| 		background: #fff; | ||||
| 		text-align: center; | ||||
| 		display: flex; | ||||
| 		.content__sign { | ||||
| 			margin-top: 10rpx; | ||||
| 			font-size: 34rpx; | ||||
| 			display: flex; | ||||
| 			align-items: center; | ||||
| 		} | ||||
| 
 | ||||
| 		.counter { | ||||
| 			font-size: 28rpx; | ||||
| 			margin: 10rpx 0; | ||||
| 			text-align: end; | ||||
| 		} | ||||
| 
 | ||||
| 		.topic { | ||||
| 			box-sizing: border-box; | ||||
| 
 | ||||
| 			.tag_title { | ||||
| 				font-size: 28rpx; | ||||
| 				background-color: #fff; | ||||
| 				color: #5ac725; | ||||
| 				border-radius: 8rpx; | ||||
| 				padding: 2rpx 8rpx; | ||||
| 				margin-right: 10rpx; | ||||
| 			} | ||||
| 
 | ||||
| 			.title { | ||||
| 				font-size: 32rpx; | ||||
| 				font-weight: 600; | ||||
| 
 | ||||
| 				.question-type { | ||||
| 					border-radius: 40rpx; | ||||
| 					padding: 4rpx 14rpx; | ||||
| 					border: 1rpx solid #3c9cff; | ||||
| 					font-size: 28rpx; | ||||
| 					color: #3c9cff; | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			.options { | ||||
| 				margin-top: 40rpx; | ||||
| 
 | ||||
| 				.item { | ||||
| 					position: relative; | ||||
| 					margin-top: 40rpx; | ||||
| 					color: #696868; | ||||
| 
 | ||||
| 					&.active { | ||||
| 						color: #3c9cff; | ||||
| 
 | ||||
| 						.option { | ||||
| 							background-color: #3c9cff; | ||||
| 							color: #fff; | ||||
| 						} | ||||
| 					} | ||||
| 
 | ||||
| 					.option { | ||||
| 						background-color: #eee; | ||||
| 						border-radius: 80rpx; | ||||
| 						width: 65rpx; | ||||
| 						height: 65rpx; | ||||
| 						line-height: 65rpx; | ||||
| 						text-align: center; | ||||
| 						font-size: 30rpx; | ||||
| 						display: inline-block; | ||||
| 					} | ||||
| 
 | ||||
| 					.text { | ||||
| 						margin-left: 30rpx; | ||||
| 						height: 60rpx; | ||||
| 						line-height: 60rpx; | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			.correct-answer { | ||||
| 				text { | ||||
| 					display: inline-block; | ||||
| 					margin-top: 10rpx; | ||||
| 					color: #696868; | ||||
| 					font-size: 30rpx; | ||||
| 					font-weight: bold; | ||||
| 				} | ||||
| 
 | ||||
| 				view { | ||||
| 					margin-top: 20rpx; | ||||
| 					color: #333; | ||||
| 					padding: 20rpx; | ||||
| 					background-color: #eee; | ||||
| 					border-radius: 10rpx; | ||||
| 					font-size: 30rpx; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		.footer { | ||||
| 			position: fixed; | ||||
| 			bottom: 0; | ||||
| 			width: 100%; | ||||
| 			left: 0; | ||||
| 			padding: 20rpx; | ||||
| 			box-sizing: border-box; | ||||
| 			background: #fff; | ||||
| 			text-align: center; | ||||
| 			display: flex; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| </style> | ||||
| </style> | ||||
|  | @ -45,7 +45,7 @@ | |||
| </template> | ||||
| 
 | ||||
| <script> | ||||
| import { getClassList, getIsUploadFace } from '@/api'; | ||||
| import { getClassList, getIsUploadFace, getStudentInfoApi } from '@/api'; | ||||
| import store from '@/store/index'; | ||||
| 
 | ||||
| export default { | ||||
|  | @ -97,6 +97,9 @@ export default { | |||
| 		 * 右上角自定义扫码图标触发事件 | ||||
| 		 */ | ||||
| 		onNavigationBarButtonTap(e) { | ||||
| 			// 调用获取学员信息的方法 | ||||
| 			getStudentInfoFunc(); | ||||
| 
 | ||||
| 			// 只允许通过手机相机扫码 | ||||
| 			uni.scanCode({ | ||||
| 				// scanType: ['qrCode'], // 仅支持二维码扫码 | ||||
|  | @ -105,8 +108,8 @@ export default { | |||
| 				success: (response) => { | ||||
| 					const { stageexampaperinputId, classId, type, } = JSON.parse(response.result) | ||||
| 					const findClassId = this.trainList.some((item) => item.classId === classId) | ||||
| 					if (type === '0') { | ||||
| 						// 签到二维码方式进入 | ||||
| 					if (type === '2') { | ||||
| 						// 签到二维码方式进入, [type: 2 --> 签到二维码方式进入] | ||||
| 						if (findClassId) { | ||||
| 							uni.$u.route({ | ||||
| 								url: '/pages/train_management/realname_info_auth', | ||||
|  | @ -118,8 +121,8 @@ export default { | |||
| 						} else { | ||||
| 							uni.$u.toast('您未在培训计划内,无法入班签到,请联系教师') | ||||
| 						} | ||||
| 					} else if (type === '1') { | ||||
| 						// 考试二维码方式进入 | ||||
| 					} else if (type === '3') { | ||||
| 						// 考试二维码方式进入 [type: 3 --> 考试二维码方式进入] | ||||
| 						if (findClassId) { | ||||
| 							uni.$u.route({ | ||||
| 								url: '/pages/train_management/face_authentication', | ||||
|  | @ -142,6 +145,13 @@ export default { | |||
| 				} | ||||
| 			}) | ||||
| 		}, | ||||
| 		/** | ||||
| 		 * 使用网络接口获取学员信息 | ||||
| 		 */ | ||||
| 		async getStudentInfoFunc() { | ||||
| 			const resData = await getStudentInfoApi(); | ||||
| 			await this.$store.dispatch('studentInfo', resData.studentInfo) | ||||
| 		}, | ||||
| 		/** | ||||
| 		 * 获取是否已经完成上传人脸信息 | ||||
| 		 */ | ||||
|  |  | |||
|  | @ -181,6 +181,17 @@ export default { | |||
| 
 | ||||
| 	onLoad(query) { | ||||
| 		this.routeQuery = query // 接收上一个页面传递过来的路由参数1 | ||||
| 		const { name,// 学员姓名, | ||||
| 			phone, // 联系电话 | ||||
|       userIdCard,// 身份证号 | ||||
|       sex, //学员性别 | ||||
|       degreeOfEducation, // 学历 | ||||
| 			} = this.$store.getters.getStudentInfo; | ||||
| 			this.ruleFormData.userInfo.name = name; | ||||
| 			this.ruleFormData.userInfo.phone = phone; | ||||
| 			this.ruleFormData.userInfo.userIdCard = userIdCard; | ||||
| 			this.ruleFormData.userInfo.sex = sex; | ||||
| 			this.ruleFormData.userInfo.degreeOfEducation = degreeOfEducation; | ||||
|   }, | ||||
| 
 | ||||
| 	methods: { | ||||
|  |  | |||
|  | @ -6,7 +6,7 @@ Vue.use(Vuex) | |||
| const store = new Vuex.Store({ | ||||
|     state: { | ||||
|         /** 人脸检测验证状态 ["0": 未完成人脸认证; "1": 已完成人脸认证] */ | ||||
|         verification: "0",  | ||||
|         verification: "0", | ||||
|         userInfo: { | ||||
|             CORPINFO_ID: '', | ||||
|             DEPARTMENT_ID: '', | ||||
|  | @ -19,14 +19,26 @@ const store = new Vuex.Store({ | |||
| 			PHOTO: "", | ||||
|             token: "" | ||||
|         }, | ||||
| 		// 这里是存储学员信息的数据,直接存储到 localStore 中的
 | ||||
| 		studentInfo: { | ||||
|             name: "" ,// 学员姓名,
 | ||||
|             phone: "", // 联系电话
 | ||||
|             userIdCard: "", // 身份证号
 | ||||
|             sex: "", // 学员性别
 | ||||
|             degreeOfEducation: "", // 学历
 | ||||
| 		} | ||||
|     }, | ||||
|     getters: { | ||||
|         getUserInfo: state => state.userInfo, | ||||
| 		getStudentInfo: state => state.studentInfo, | ||||
|         getVerification: state => state.verification, | ||||
|     }, | ||||
|     mutations: { | ||||
|         setUserInfo(state, userInfo) { | ||||
|             state.userInfo = userInfo | ||||
|         }, | ||||
| 		setStudentInfo(state, studentInfo) { | ||||
|             state.studentInfo = studentInfo | ||||
|         }, | ||||
|         setVerification(state, verification) { | ||||
|             state.verification = verification | ||||
|  | @ -36,6 +48,9 @@ const store = new Vuex.Store({ | |||
|         setUserInfo({commit}, userInfo) { | ||||
|             commit('setUserInfo', userInfo) | ||||
|         }, | ||||
| 		setStudentInfo(state, studentInfo) { | ||||
| 			commit('setStudentInfo', studentInfo) | ||||
| 		}, | ||||
|         setVerification({commit}, verification) { | ||||
|             commit('setVerification', verification) | ||||
|         }, | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue