yangg 2 tháng trước cách đây
mục cha
commit
4487362fd6

+ 207 - 140
pages/camera/camera.vue

@@ -1,91 +1,61 @@
 <template>
 	<view class="camera-container">
-		<!-- 顶部标题栏 -->
-		<!-- <view class="header">
-			<view class="back-button" @click="back">
-				<text class="iconfont icon-back">&#xe679;</text>
+		<!-- 顶部相机区域 - 固定位置 -->
+		<view class="fixed-camera-container">
+			<view class="user-avatar">
+				<camera v-if="!digitalHumanUrl" device-position="front" flash="auto" class="camera" 
+						:mode="mode" @error="handleCameraError"></camera>
+				<web-view v-else-if="digitalHumanUrl" :src="digitalHumanUrl" class="digital-human-webview"></web-view>
+				<image v-else src="/static/avatar.png" mode="aspectFill" class="avatar-image"></image>
 			</view>
-			<view class="title">中国传统文化测试</view>
-			<view class="controls">
-				<text class="iconfont icon-mic">&#xe677;</text>
-        <text class="iconfont icon-settings" @click="toggleSettings">&#xe678;</text>
-			</view>
-		</view> -->
+		</view>
 
-		<!-- 主要内容区域 - 添加可滚动区域 -->
-		<scroll-view class="content-scroll" scroll-y="true">
+		<!-- 主要内容区域 - 修改为流式布局 -->
+		<scroll-view class="content-scroll" scroll-y="true" :scroll-into-view="currentScrollId" :scroll-with-animation="true">
 			<view class="content">
-				<!-- 数字人头像 -->
-				<view class="digital-avatar">
-					<!-- <view class="message-box">
-						<text class="message-text">面试官会根据您的自我介绍内容对您提出以下问题,请您回答相关问题,请知悉答题即可</text>
-					</view> -->
-					<view class="user-avatar">
-						<camera v-if="!digitalHumanUrl" device-position="front" flash="auto" class="camera" 
-								:mode="mode" @error="handleCameraError"></camera>
-						<web-view v-else-if="digitalHumanUrl" :src="digitalHumanUrl" class="digital-human-webview"></web-view>
-						<image v-else src="/static/avatar.png" mode="aspectFill" class="avatar-image"></image>
-					</view>
-				</view>
-
-				<!-- 进度指示器 -->
-				<!-- <view class="progress-container">
-	        <view class="progress-step" v-for="(step, index) in 3" :key="index">
-	          <view class="step-circle" :class="{'active': currentStep >= index+1}">{{index+1}}</view>
-	          <view class="step-text">{{stepTexts[index]}}</view>
-	        </view>
-	        <view class="progress-bar">
-	          <view class="progress-fill" :style="{width: progressWidth + '%'}"></view>
-	        </view>
-	      </view> -->
-
-				<!-- 测试内容区域 -->
-				<view class="interview-content">
+				<!-- 测试内容区域 - 修改为流式布局,每个问题都显示 -->
+				<view v-for="(question, qIndex) in questions" :key="question.id" :id="'question-'+qIndex" class="interview-content">
 					<!-- 问题编号和进度 -->
 					<view class="question-number">
-						<text>{{currentQuestionIndex + 1}}/{{questions.length}}</text>
+						<text>{{qIndex + 1}}/{{questions.length}}</text>
 					</view>
 					
 					<!-- 问题和选项区域 -->
 					<view class="question-area">
 						<view class="question-importance">
 							<!-- <text v-if="currentQuestion.isImportant">重点题</text>  -->
-							<text class="question-type">{{currentQuestion.questionTypeName}}</text> 
-							{{currentQuestion.text}}
+							<text class="question-type">{{question.questionTypeName}}</text> 
+							{{question.text}}
 						</view>
 
 						<!-- 添加图片显示区域,仅在 question_form 为 3 时显示 -->
-						<view class="question-image-container" v-if="currentQuestion.questionType === 3 && currentQuestion.imageUrl">
-							<image :src="currentQuestion.imageUrl" mode="widthFix" class="question-image"></image>
+						<view class="question-image-container" v-if="question.questionType === 3 && question.imageUrl">
+							<image :src="question.imageUrl" mode="widthFix" class="question-image"></image>
 						</view>
 
 						<view class="options">
-							<!-- 渲染非开放问题 (questionType: 1, 2 或 3) 'option-correct': showResult && (
-										currentQuestion.questionType === 1 || currentQuestion.questionType === 3 ? index === currentQuestion.correctAnswer : currentQuestion.correctAnswers.includes(index)
-									),-->
+							<!-- 渲染非开放问题 (questionType: 1, 2 或 3) -->
 							<view 
-								v-if="currentQuestion.questionType !== 0"
-								v-for="(option, index) in currentQuestion.options" 
+								v-if="question.questionType !== 0"
+								v-for="(option, index) in question.options" 
 								:key="index" 
 								class="option-item"
 								:class="{
-									'option-selected': currentQuestion.questionType === 1 || currentQuestion.questionType === 3 ? selectedOption === index : selectedOptions.includes(index),
-									
-									
+									'option-selected': isOptionSelected(question, qIndex, index),
+									'option-disabled': qIndex !== currentQuestionIndex
 								}" 
-								@click="selectOption(index)">
-								<!-- 使用字母标识 A、B、C、D、E 等 -->
-								<!-- <text class="option-prefix">{{ String.fromCharCode(65 + index) }}.</text> -->
+								@click="qIndex === currentQuestionIndex && selectOption(index)">
 								<text class="option-text">{{ option.option_text || (typeof option === 'string' ? option : JSON.stringify(option)) }}</text>
 							</view>
 						</view>
 
-						<!-- 添加计时器显示 -->
-						<!-- <view class="timer-container">
-							<text class="timer-text">本题剩余({{remainingTime}})</text>
-						</view> -->
-						
-						<!-- 移除底部按钮容器,将在滚动区域外显示 -->
+						<!-- 添加当前题目的按钮 - 只在多选题时显示 -->
+						<view class="question-button-container" v-if="qIndex === currentQuestionIndex && question.questionType === 2">
+							<button class="next-button" @click="nextQuestion()" 
+								:disabled="selectedOptions.length === 0">
+								{{"提交答案"}}
+							</button>
+						</view>
 					</view>
 				</view>
 				
@@ -94,26 +64,6 @@
 			</view>
 		</scroll-view>
 		
-		<!-- 将底部按钮移到滚动区域外 -->
-		<view class="bottom-button-container">
-			<view class="bottom-button-wrapper">
-				<button class="next-button" @click="nextQuestion(option)" 
-					:disabled="
-						(currentQuestion.questionType === 0 && openQuestionAnswer.trim() === '') || 
-						(currentQuestion.questionType === 1 && selectedOption === null) || 
-						(currentQuestion.questionType === 2 && selectedOptions.length === 0)
-					">
-					本题剩余{{remainingTime}}&nbsp;&nbsp;&nbsp;{{"进入下一题"}}
-				</button>
-			</view>
-		</view>
-
-		<!-- 底部控制栏 -->
-		<!-- <view class="footer">
-			<view class="timer">本题剩余 {{remainingTime}}</view>
-			<view class="next-step">进入下一题</view>
-		</view> -->
-
 		<!-- 面试结束弹窗 -->
 		<view class="interview-end-modal" v-if="showEndModal">
 			<view class="modal-content">
@@ -193,6 +143,7 @@
 				currentAnswer: null, // 存储当前答案以便提交
 				questionStartTime: null, // 存储问题开始时间
 				mode: 'normal', // 相机模式
+				currentScrollId: 'question-0', // 当前滚动到的问题ID
 			}
 		},
 		computed: {
@@ -273,10 +224,10 @@
 					// 设置总题目数
 					this.totalQuestions = this.questions.length;
 					
-					// 启动倒计时
+					/* // 启动倒计时
 					if (this.questions.length > 0) {
 						this.startTimer();
-					}
+					} */
 				} catch (error) {
 					console.error('获取面试详情失败:', error);
 					this.handleLoadError('获取面试详情失败');
@@ -314,8 +265,8 @@
 					// 设置总题目数
 					this.totalQuestions = this.questions.length;
 					
-					// 启动倒计时
-					this.startTimer();
+					/* // 启动倒计时
+					this.startTimer(); */
 				} else {
 					this.handleLoadError('没有可用的选择题');
 				}
@@ -365,7 +316,7 @@
 						}
 					}
 					
-					// 格式化显示时间
+					// 格式化显示时间 (不再显示,但仍然计算用于内部逻辑)
 					const min = Math.floor(seconds / 60).toString().padStart(2, '0');
 					const sec = (seconds % 60).toString().padStart(2, '0');
 					this.remainingTime = `${min}:${sec}`;
@@ -374,7 +325,7 @@
 
 			resetTimer() {
 				clearInterval(this.timerInterval);
-				this.startTimer();
+				/* this.startTimer(); */
 			},
 
 			selectOption(index) {
@@ -390,11 +341,47 @@
 						// 否则添加到已选中数组
 						this.selectedOptions.push(index);
 					}
+					// 多选题不自动提交,需要用户手动点击"进入下一题"按钮
 				} else if (this.currentQuestion.questionType === 1 || this.currentQuestion.questionType === 3) { // 单选题或看图答题
 					this.selectedOption = index;
+					
+					// 单选题自动提交答案并进入下一题
+					this.playAiSpeaking();
+					
+					// 短暂延迟后提交答案,让用户看到选中效果
+					setTimeout(() => {
+						this.checkAnswer();
+						this.saveAnswer();
+						
+						// 提交答案
+						this.submitCurrentAnswer().then(() => {
+							// 提交成功后,短暂延迟后自动进入下一题
+							setTimeout(() => {
+								// 如果是最后一题,跳转到面试页面
+								if (this.currentQuestionIndex >= this.questions.length - 1) {
+									uni.navigateTo({
+										url: '/pages/interview-question/interview-question'
+									});
+								} else {
+									// 否则进入下一题
+									this.goToNextQuestion();
+								}
+							}, 800); // 0.8秒后自动进入下一题
+						}).catch(error => {
+							console.error('提交答案失败:', error);
+							// 即使提交失败也继续下一题
+							setTimeout(() => {
+								if (this.currentQuestionIndex >= this.questions.length - 1) {
+									uni.navigateTo({
+										url: '/pages/interview-question/interview-question'
+									});
+								} else {
+									this.goToNextQuestion();
+								}
+							}, 1000);
+						});
+					}, 500); // 0.5秒后提交答案
 				}
-				
-				this.playAiSpeaking();
 			},
 			
 			checkAnswer() {
@@ -433,55 +420,44 @@
 				this.saveAnswer();
 			},
 
-			nextQuestion(data) {
-				// 如果还没有显示结果,先检查答案并提交
-				if (!this.showResult) {
-					this.checkAnswer();
-					
-					// 保存当前题目的答案
-					this.saveAnswer();
-					
-					// 提交答案
-					this.submitCurrentAnswer().then(() => {
-						// 提交成功后,短暂延迟后自动进入下一题
-						setTimeout(() => {
-							// 如果是最后一题,跳转到面试页面
-							if (this.currentQuestionIndex >= this.questions.length - 1) {
-								uni.navigateTo({
-									url: '/pages/interview-question/interview-question'
-								});
-							} else {
-								// 否则进入下一题
-								this.goToNextQuestion();
-							}
-						}, 500); // 0.5秒后自动进入下一题
-					}).catch(error => {
-						console.error('提交答案失败:', error);
-						// 即使提交失败也继续下一题
-						setTimeout(() => {
-							if (this.currentQuestionIndex >= this.questions.length - 1) {
-								uni.navigateTo({
-									url: '/pages/interview-question/interview-question'
-								});
-							} else {
-								this.goToNextQuestion();
-							}
-						}, 1000);
-					});
-					return;
-				}
+			// 修改 nextQuestion 方法,只处理多选题
+			nextQuestion() {
+				// 确保当前是多选题
+				if (this.currentQuestion.questionType !== 2) return;
 				
-				// 如果已经显示结果,点击"下一题"按钮时直接执行
-				// 如果是最后一题,直接跳转到手部照片采集页面
-				if (this.currentQuestionIndex >= this.questions.length - 1) {
-					uni.navigateTo({
-						url: '/pages/interview-question/interview-question'
-					});
-					return;
-				}
+				// 检查答案并提交
+				this.checkAnswer();
 				
-				// 前往下一题
-				this.goToNextQuestion();
+				// 保存当前题目的答案
+				this.saveAnswer();
+				
+				// 提交答案
+				this.submitCurrentAnswer().then(() => {
+					// 提交成功后,短暂延迟后自动进入下一题
+					setTimeout(() => {
+						// 如果是最后一题,跳转到面试页面
+						if (this.currentQuestionIndex >= this.questions.length - 1) {
+							uni.navigateTo({
+								url: '/pages/interview-question/interview-question'
+							});
+						} else {
+							// 否则进入下一题
+							this.goToNextQuestion();
+						}
+					}, 500); // 0.5秒后自动进入下一题
+				}).catch(error => {
+					console.error('提交答案失败:', error);
+					// 即使提交失败也继续下一题
+					setTimeout(() => {
+						if (this.currentQuestionIndex >= this.questions.length - 1) {
+							uni.navigateTo({
+								url: '/pages/interview-question/interview-question'
+							});
+						} else {
+							this.goToNextQuestion();
+						}
+					}, 1000);
+				});
 			},
 
 			// 保存当前题目的答案
@@ -609,10 +585,11 @@
 				}
 			},
 			
-			// 修改 goToNextQuestion 方法,添加 async 关键字
+			// 修改 goToNextQuestion 方法,在切换到下一题时重置当前选项状态
 			async goToNextQuestion() {
 				// 重置状态
 				this.showResult = false;
+				// 重置当前选择状态,但不影响已保存的答案
 				this.selectedOption = null;
 				this.selectedOptions = [];
 				this.openQuestionAnswer = ''; // 重置开放问题答案
@@ -620,12 +597,15 @@
 				// 前往下一题
 				this.currentQuestionIndex++;
 				
+				// 更新滚动ID,滚动到下一题
+				this.currentScrollId = 'question-' + this.currentQuestionIndex;
+				
 				// 如果已经有下一题的详情,直接使用
 				if (this.questions[this.currentQuestionIndex]) {
 					// 更新进度
 					this.progressWidth = (this.currentQuestionIndex + 1) / this.questions.length * 100;
 					
-					// 重置计时器
+					// 重置计时器但不显示
 					this.resetTimer();
 					
 					// 播放AI介绍下一题
@@ -842,6 +822,31 @@
 					icon: 'none'
 				});
 			},
+
+			// 修改 isOptionSelected 方法,更精确地判断选项是否被选中
+			isOptionSelected(question, qIndex, optionIndex) {
+				// 获取该题的答案
+				const answer = this.answers.find(a => a.questionId === question.id);
+				
+				// 如果是当前正在回答的题目
+				if (qIndex === this.currentQuestionIndex) {
+					if (question.questionType === 1 || question.questionType === 3) { // 单选题
+						return this.selectedOption === optionIndex;
+					} else if (question.questionType === 2) { // 多选题
+						return this.selectedOptions.includes(optionIndex);
+					}
+				} 
+				// 如果是已回答过的题目,使用保存的答案
+				else if (answer) {
+					if (question.questionType === 1 || question.questionType === 3) { // 单选题
+						return answer.answer === optionIndex;
+					} else if (question.questionType === 2 && Array.isArray(answer.answer)) { // 多选题
+						return answer.answer.includes(optionIndex);
+					}
+				}
+				
+				return false;
+			},
 		},
 		// 添加生命周期钩子,确保在组件销毁时清除计时器
 		beforeDestroy() {
@@ -957,6 +962,9 @@
 		flex: 1;
 		display: flex;
 		flex-direction: column;
+		margin-bottom: 40rpx;
+		padding: 20rpx;
+		border-bottom: 1px solid #eee;
 	}
 
 	.video-area {
@@ -1048,12 +1056,29 @@
 		border: 1px solid #e0e0e0;
 		display: flex;
 		align-items: center;
+		cursor: pointer; /* 添加指针样式 */
+	}
+
+	.option-item:active {
+		transform: scale(0.98); /* 点击时轻微缩小效果 */
+		opacity: 0.9;
 	}
 
 	.option-selected {
 		background-color: #e6f7ff;
 		border: 1px solid #1890ff;
 	}
+
+	/* 添加选中后的动画效果 */
+	@keyframes selectedPulse {
+		0% { box-shadow: 0 0 0 0 rgba(24, 144, 255, 0.4); }
+		70% { box-shadow: 0 0 0 10px rgba(24, 144, 255, 0); }
+		100% { box-shadow: 0 0 0 0 rgba(24, 144, 255, 0); }
+	}
+
+	.option-selected {
+		animation: selectedPulse 1.5s ease-out;
+	}
 	
 	.option-correct {
 		background-color: #d4f7d4;
@@ -1415,12 +1440,54 @@
 	/* 添加滚动视图样式 */
 	.content-scroll {
 		flex: 1;
-		height: calc(100vh - 130px); /* 减去底部按钮的高度 */
-		overflow-y: auto;
+		height: calc(100vh - 200px); /* 只减去顶部相机的高度 */
+		margin-top: 10px;
 	}
 
 	/* 添加底部空白区域,防止内容被固定按钮遮挡 */
 	.bottom-space {
-		height: 130px; /* 与底部按钮高度一致 */
+		height: 50rpx; /* 减小底部空白区域 */
+	}
+
+	/* 添加流式布局相关样式 */
+	.interview-content {
+		margin-bottom: 40rpx;
+		padding: 20rpx;
+		border-bottom: 1px solid #eee;
+	}
+	
+	.option-disabled {
+		opacity: 0.7;
+		pointer-events: none;
+	}
+	
+	.question-button-container {
+		margin-top: 20rpx;
+		display: flex;
+		justify-content: center;
+	}
+	
+	.bottom-timer-container {
+		display: none;
+	}
+
+	/* 添加固定相机容器样式 */
+	.fixed-camera-container {
+		position: sticky;
+		top: 0;
+		width: 100%;
+		padding: 20rpx;
+		background-color: #fff;
+		z-index: 10;
+		display: flex;
+		justify-content: flex-start;
+		border-bottom: 1px solid #eee;
+	}
+	
+	.user-avatar {
+		width: 110px;
+		height: 160px;
+		border-radius: 10rpx;
+		overflow: hidden;
 	}
 </style>

+ 1 - 1
pages/face-photo/face-photo.vue

@@ -280,7 +280,7 @@ export default {
         });
         return;
       }
-      
+      console.log(this.mediaSource);
       // 使用uni.uploadFile直接上传文件,类似interview页面的实现
       uni.uploadFile({
         url: `${apiBaseUrl}/job/upload_posture_photo`,

+ 30 - 2
pages/interview/interview.vue

@@ -297,7 +297,14 @@ import { apiBaseUrl } from '@/common/config.js'; // Import the base URL from a c
 						uni.hideLoading();
 						uni.showToast({
 							title: '照片上传成功',
-							icon: 'success'
+							icon: 'success',
+							duration: 1500,
+							success: () => {
+								// 上传成功后自动进入下一步
+								setTimeout(() => {
+									this.autoNextStep();
+								}, 1500);
+							}
 						});
 					})
 					.catch(error => {
@@ -352,7 +359,14 @@ import { apiBaseUrl } from '@/common/config.js'; // Import the base URL from a c
 							uni.hideLoading();
 							uni.showToast({
 								title: '照片上传成功',
-								icon: 'success'
+								icon: 'success',
+								duration: 1500,
+								success: () => {
+									// 上传成功后自动进入下一步
+									setTimeout(() => {
+										this.autoNextStep();
+									}, 1500);
+								}
 							});
 						},
 						fail: (err) => {
@@ -675,6 +689,20 @@ import { apiBaseUrl } from '@/common/config.js'; // Import the base URL from a c
 					this.stopMediaStream();
 					this.startCamera();
 				}
+			},
+			
+			// 添加自动进入下一步的方法
+			autoNextStep() {
+				if (this.currentStep < 5) {
+					this.currentStep++;
+					// 如果不是最后一步,自动开始拍摄下一张照片
+					if (this.currentStep < 6) {
+						this.takePhoto();
+					}
+				} else if (this.currentStep === 5 && this.photos[5]) {
+					// 所有照片都已拍摄完成,进行提交
+					this.submitAllPhotos();
+				}
 			}
 		}
 	}

+ 2 - 2
pages/interview_success/interview_success.vue

@@ -40,8 +40,8 @@
 				uni.navigateBack();
 			},
 			goNext() {
-				// 进入下一步
-				uni.navigateTo({
+				// 关闭所有页面,打开新页面
+				uni.reLaunch({
 					url: '/pages/success/success'
 				});
 			}

+ 1 - 1
pages/my/my.vue

@@ -80,7 +80,7 @@ export default {
 	},
 	onLoad() {
 		// 每次显示页面时检查登录状态
-		this.checkLogin();
+		//this.checkLogin();
 	},
 	onShow() {
 		// 每次显示页面时检查登录状态

+ 118 - 73
unpackage/dist/dev/mp-weixin/pages/camera/camera.js

@@ -48,8 +48,10 @@ const _sfc_main = {
       // 存储当前答案以便提交
       questionStartTime: null,
       // 存储问题开始时间
-      mode: "normal"
+      mode: "normal",
       // 相机模式
+      currentScrollId: "question-0"
+      // 当前滚动到的问题ID
     };
   },
   computed: {
@@ -112,9 +114,6 @@ const _sfc_main = {
         }
         console.log(this.questions);
         this.totalQuestions = this.questions.length;
-        if (this.questions.length > 0) {
-          this.startTimer();
-        }
       } catch (error) {
         console.error("获取面试详情失败:", error);
         this.handleLoadError("获取面试详情失败");
@@ -144,7 +143,6 @@ const _sfc_main = {
         };
         this.questions.push(formattedQuestion);
         this.totalQuestions = this.questions.length;
-        this.startTimer();
       } else {
         this.handleLoadError("没有可用的选择题");
       }
@@ -190,7 +188,6 @@ const _sfc_main = {
     },
     resetTimer() {
       clearInterval(this.timerInterval);
-      this.startTimer();
     },
     selectOption(index) {
       if (this.showResult)
@@ -204,8 +201,34 @@ const _sfc_main = {
         }
       } else if (this.currentQuestion.questionType === 1 || this.currentQuestion.questionType === 3) {
         this.selectedOption = index;
+        this.playAiSpeaking();
+        setTimeout(() => {
+          this.checkAnswer();
+          this.saveAnswer();
+          this.submitCurrentAnswer().then(() => {
+            setTimeout(() => {
+              if (this.currentQuestionIndex >= this.questions.length - 1) {
+                common_vendor.index.navigateTo({
+                  url: "/pages/interview-question/interview-question"
+                });
+              } else {
+                this.goToNextQuestion();
+              }
+            }, 800);
+          }).catch((error) => {
+            console.error("提交答案失败:", error);
+            setTimeout(() => {
+              if (this.currentQuestionIndex >= this.questions.length - 1) {
+                common_vendor.index.navigateTo({
+                  url: "/pages/interview-question/interview-question"
+                });
+              } else {
+                this.goToNextQuestion();
+              }
+            }, 1e3);
+          });
+        }, 500);
       }
-      this.playAiSpeaking();
     },
     checkAnswer() {
       if (this.showResult)
@@ -231,41 +254,34 @@ const _sfc_main = {
       this.showResult = true;
       this.saveAnswer();
     },
-    nextQuestion(data) {
-      if (!this.showResult) {
-        this.checkAnswer();
-        this.saveAnswer();
-        this.submitCurrentAnswer().then(() => {
-          setTimeout(() => {
-            if (this.currentQuestionIndex >= this.questions.length - 1) {
-              common_vendor.index.navigateTo({
-                url: "/pages/interview-question/interview-question"
-              });
-            } else {
-              this.goToNextQuestion();
-            }
-          }, 500);
-        }).catch((error) => {
-          console.error("提交答案失败:", error);
-          setTimeout(() => {
-            if (this.currentQuestionIndex >= this.questions.length - 1) {
-              common_vendor.index.navigateTo({
-                url: "/pages/interview-question/interview-question"
-              });
-            } else {
-              this.goToNextQuestion();
-            }
-          }, 1e3);
-        });
-        return;
-      }
-      if (this.currentQuestionIndex >= this.questions.length - 1) {
-        common_vendor.index.navigateTo({
-          url: "/pages/interview-question/interview-question"
-        });
+    // 修改 nextQuestion 方法,只处理多选题
+    nextQuestion() {
+      if (this.currentQuestion.questionType !== 2)
         return;
-      }
-      this.goToNextQuestion();
+      this.checkAnswer();
+      this.saveAnswer();
+      this.submitCurrentAnswer().then(() => {
+        setTimeout(() => {
+          if (this.currentQuestionIndex >= this.questions.length - 1) {
+            common_vendor.index.navigateTo({
+              url: "/pages/interview-question/interview-question"
+            });
+          } else {
+            this.goToNextQuestion();
+          }
+        }, 500);
+      }).catch((error) => {
+        console.error("提交答案失败:", error);
+        setTimeout(() => {
+          if (this.currentQuestionIndex >= this.questions.length - 1) {
+            common_vendor.index.navigateTo({
+              url: "/pages/interview-question/interview-question"
+            });
+          } else {
+            this.goToNextQuestion();
+          }
+        }, 1e3);
+      });
     },
     // 保存当前题目的答案
     saveAnswer() {
@@ -364,13 +380,14 @@ const _sfc_main = {
         this.isSubmitting = false;
       }
     },
-    // 修改 goToNextQuestion 方法,添加 async 关键字
+    // 修改 goToNextQuestion 方法,在切换到下一题时重置当前选项状态
     async goToNextQuestion() {
       this.showResult = false;
       this.selectedOption = null;
       this.selectedOptions = [];
       this.openQuestionAnswer = "";
       this.currentQuestionIndex++;
+      this.currentScrollId = "question-" + this.currentQuestionIndex;
       if (this.questions[this.currentQuestionIndex]) {
         this.progressWidth = (this.currentQuestionIndex + 1) / this.questions.length * 100;
         this.resetTimer();
@@ -508,6 +525,24 @@ const _sfc_main = {
         title: "相机启动失败,请检查权限设置",
         icon: "none"
       });
+    },
+    // 修改 isOptionSelected 方法,更精确地判断选项是否被选中
+    isOptionSelected(question, qIndex, optionIndex) {
+      const answer = this.answers.find((a) => a.questionId === question.id);
+      if (qIndex === this.currentQuestionIndex) {
+        if (question.questionType === 1 || question.questionType === 3) {
+          return this.selectedOption === optionIndex;
+        } else if (question.questionType === 2) {
+          return this.selectedOptions.includes(optionIndex);
+        }
+      } else if (answer) {
+        if (question.questionType === 1 || question.questionType === 3) {
+          return answer.answer === optionIndex;
+        } else if (question.questionType === 2 && Array.isArray(answer.answer)) {
+          return answer.answer.includes(optionIndex);
+        }
+      }
+      return false;
     }
   },
   // 添加生命周期钩子,确保在组件销毁时清除计时器
@@ -533,50 +568,60 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
     f: common_assets._imports_0$1
   }, {
     d: $data.digitalHumanUrl,
-    g: common_vendor.t($data.currentQuestionIndex + 1),
+    g: common_vendor.f($data.questions, (question, qIndex, i0) => {
+      return common_vendor.e({
+        a: common_vendor.t(qIndex + 1),
+        b: common_vendor.t(question.questionTypeName),
+        c: common_vendor.t(question.text),
+        d: question.questionType === 3 && question.imageUrl
+      }, question.questionType === 3 && question.imageUrl ? {
+        e: question.imageUrl
+      } : {}, {
+        f: question.questionType !== 0
+      }, question.questionType !== 0 ? {
+        g: common_vendor.f(question.options, (option, index, i1) => {
+          return {
+            a: common_vendor.t(option.option_text || (typeof option === "string" ? option : JSON.stringify(option))),
+            b: index,
+            c: $options.isOptionSelected(question, qIndex, index) ? 1 : "",
+            d: common_vendor.o(($event) => qIndex === $data.currentQuestionIndex && $options.selectOption(index), index)
+          };
+        }),
+        h: qIndex !== $data.currentQuestionIndex ? 1 : ""
+      } : {}, {
+        i: qIndex === $data.currentQuestionIndex && question.questionType === 2
+      }, qIndex === $data.currentQuestionIndex && question.questionType === 2 ? {
+        j: common_vendor.t("提交答案"),
+        k: common_vendor.o(($event) => $options.nextQuestion(), question.id),
+        l: $data.selectedOptions.length === 0
+      } : {}, {
+        m: question.id,
+        n: "question-" + qIndex
+      });
+    }),
     h: common_vendor.t($data.questions.length),
-    i: common_vendor.t($options.currentQuestion.questionTypeName),
-    j: common_vendor.t($options.currentQuestion.text),
-    k: $options.currentQuestion.questionType === 3 && $options.currentQuestion.imageUrl
-  }, $options.currentQuestion.questionType === 3 && $options.currentQuestion.imageUrl ? {
-    l: $options.currentQuestion.imageUrl
-  } : {}, {
-    m: $options.currentQuestion.questionType !== 0
-  }, $options.currentQuestion.questionType !== 0 ? {
-    n: common_vendor.f($options.currentQuestion.options, (option, index, i0) => {
-      return {
-        a: common_vendor.t(option.option_text || (typeof option === "string" ? option : JSON.stringify(option))),
-        b: index,
-        c: ($options.currentQuestion.questionType === 1 || $options.currentQuestion.questionType === 3 ? $data.selectedOption === index : $data.selectedOptions.includes(index)) ? 1 : "",
-        d: common_vendor.o(($event) => $options.selectOption(index), index)
-      };
-    })
-  } : {}, {
-    o: common_vendor.t($data.remainingTime),
-    p: common_vendor.t("进入下一题"),
-    q: common_vendor.o(($event) => $options.nextQuestion(_ctx.option)),
-    r: $options.currentQuestion.questionType === 0 && $data.openQuestionAnswer.trim() === "" || $options.currentQuestion.questionType === 1 && $data.selectedOption === null || $options.currentQuestion.questionType === 2 && $data.selectedOptions.length === 0,
-    s: $data.showEndModal
+    i: $data.currentScrollId,
+    j: $data.showEndModal
   }, $data.showEndModal ? {
-    t: common_vendor.o((...args) => $options.navigateToInterview && $options.navigateToInterview(...args))
+    k: common_vendor.o((...args) => $options.navigateToInterview && $options.navigateToInterview(...args))
   } : {}, {
-    v: $data.interviewCompleted
+    l: $data.interviewCompleted
   }, $data.interviewCompleted ? {
-    w: common_assets._imports_0$1,
-    x: common_vendor.o((...args) => $options.back && $options.back(...args))
+    m: common_assets._imports_0$1,
+    n: common_vendor.o((...args) => $options.back && $options.back(...args))
   } : {}, {
-    y: $data.loading
+    o: $data.loading
   }, $data.loading ? {
-    z: common_vendor.p({
+    p: common_vendor.p({
       status: "loading",
       contentText: {
         contentdown: "加载中..."
       }
     })
   } : {}, {
-    A: !$data.loading && $data.loadError
+    q: !$data.loading && $data.loadError
   }, !$data.loading && $data.loadError ? {
-    B: common_vendor.o((...args) => $options.fetchInterviewData && $options.fetchInterviewData(...args))
+    r: common_vendor.o((...args) => $options.fetchInterviewData && $options.fetchInterviewData(...args))
   } : {});
 }
 const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render]]);

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
unpackage/dist/dev/mp-weixin/pages/camera/camera.wxml


+ 63 - 3
unpackage/dist/dev/mp-weixin/pages/camera/camera.wxss

@@ -89,6 +89,9 @@
 		flex: 1;
 		display: flex;
 		flex-direction: column;
+		margin-bottom: 40rpx;
+		padding: 20rpx;
+		border-bottom: 1px solid #eee;
 }
 .video-area {
 		display: flex;
@@ -168,11 +171,29 @@
 		border: 1px solid #e0e0e0;
 		display: flex;
 		align-items: center;
+		cursor: pointer; /* 添加指针样式 */
+}
+.option-item:active {
+		transform: scale(0.98); /* 点击时轻微缩小效果 */
+		opacity: 0.9;
 }
 .option-selected {
 		background-color: #e6f7ff;
 		border: 1px solid #1890ff;
 }
+
+	/* 添加选中后的动画效果 */
+@keyframes selectedPulse {
+0% { box-shadow: 0 0 0 0 rgba(24, 144, 255, 0.4);
+}
+70% { box-shadow: 0 0 0 10px rgba(24, 144, 255, 0);
+}
+100% { box-shadow: 0 0 0 0 rgba(24, 144, 255, 0);
+}
+}
+.option-selected {
+		animation: selectedPulse 1.5s ease-out;
+}
 .option-correct {
 		background-color: #d4f7d4;
 		border: 1px solid #52c41a;
@@ -489,11 +510,50 @@
 	/* 添加滚动视图样式 */
 .content-scroll {
 		flex: 1;
-		height: calc(100vh - 130px); /* 减去底部按钮的高度 */
-		overflow-y: auto;
+		height: calc(100vh - 200px); /* 只减去顶部相机的高度 */
+		margin-top: 10px;
 }
 
 	/* 添加底部空白区域,防止内容被固定按钮遮挡 */
 .bottom-space {
-		height: 130px; /* 与底部按钮高度一致 */
+		height: 50rpx; /* 减小底部空白区域 */
+}
+
+	/* 添加流式布局相关样式 */
+.interview-content {
+		margin-bottom: 40rpx;
+		padding: 20rpx;
+		border-bottom: 1px solid #eee;
+}
+.option-disabled {
+		opacity: 0.7;
+		pointer-events: none;
+}
+.question-button-container {
+		margin-top: 20rpx;
+		display: flex;
+		justify-content: center;
+}
+.bottom-timer-container {
+		display: none;
+}
+
+	/* 添加固定相机容器样式 */
+.fixed-camera-container {
+		position: -webkit-sticky;
+		position: sticky;
+		top: 0;
+		width: 100%;
+		padding: 20rpx;
+		background-color: #fff;
+		z-index: 10;
+		display: flex;
+		justify-content: flex-start;
+		border-bottom: 1px solid #eee;
+}
+.user-avatar {
+		width: 110px;
+		height: 160px;
+		border-radius: 10rpx;
+		overflow: hidden;
 }

+ 1 - 0
unpackage/dist/dev/mp-weixin/pages/face-photo/face-photo.js

@@ -212,6 +212,7 @@ const _sfc_main = {
         });
         return;
       }
+      console.log(this.mediaSource);
       common_vendor.index.uploadFile({
         url: `${common_config.apiBaseUrl}/job/upload_posture_photo`,
         filePath: this.mediaSource,

+ 25 - 2
unpackage/dist/dev/mp-weixin/pages/interview/interview.js

@@ -153,7 +153,13 @@ const _sfc_main = {
           common_vendor.index.hideLoading();
           common_vendor.index.showToast({
             title: "照片上传成功",
-            icon: "success"
+            icon: "success",
+            duration: 1500,
+            success: () => {
+              setTimeout(() => {
+                this.autoNextStep();
+              }, 1500);
+            }
           });
         }).catch((error) => {
           console.error("照片上传失败:", error);
@@ -202,7 +208,13 @@ const _sfc_main = {
             common_vendor.index.hideLoading();
             common_vendor.index.showToast({
               title: "照片上传成功",
-              icon: "success"
+              icon: "success",
+              duration: 1500,
+              success: () => {
+                setTimeout(() => {
+                  this.autoNextStep();
+                }, 1500);
+              }
             });
           },
           fail: (err) => {
@@ -459,6 +471,17 @@ const _sfc_main = {
         this.stopMediaStream();
         this.startCamera();
       }
+    },
+    // 添加自动进入下一步的方法
+    autoNextStep() {
+      if (this.currentStep < 5) {
+        this.currentStep++;
+        if (this.currentStep < 6) {
+          this.takePhoto();
+        }
+      } else if (this.currentStep === 5 && this.photos[5]) {
+        this.submitAllPhotos();
+      }
     }
   }
 };

+ 1 - 1
unpackage/dist/dev/mp-weixin/pages/interview_success/interview_success.js

@@ -18,7 +18,7 @@ const _sfc_main = {
       common_vendor.index.navigateBack();
     },
     goNext() {
-      common_vendor.index.navigateTo({
+      common_vendor.index.reLaunch({
         url: "/pages/success/success"
       });
     }

+ 0 - 1
unpackage/dist/dev/mp-weixin/pages/my/my.js

@@ -29,7 +29,6 @@ const _sfc_main = {
     };
   },
   onLoad() {
-    this.checkLogin();
   },
   onShow() {
     this.checkLoginStatus();

+ 1 - 1
unpackage/dist/dev/mp-weixin/project.config.json

@@ -8,7 +8,7 @@
     "urlCheck": false,
     "es6": true,
     "postcss": false,
-    "minified": true,
+    "minified": false,
     "newFeature": true,
     "bigPackageSizeSupport": true,
     "babelSetting": {

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác