|
@@ -12,90 +12,97 @@
|
|
</view>
|
|
</view>
|
|
</view> -->
|
|
</view> -->
|
|
|
|
|
|
- <!-- 主要内容区域 -->
|
|
|
|
- <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>
|
|
|
|
|
|
+ <!-- 主要内容区域 - 添加可滚动区域 -->
|
|
|
|
+ <scroll-view class="content-scroll" scroll-y="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>
|
|
- </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 class="question-number">
|
|
|
|
- <text>{{currentQuestionIndex + 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}}
|
|
|
|
|
|
+ <!-- 进度指示器 -->
|
|
|
|
+ <!-- <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 class="question-number">
|
|
|
|
+ <text>{{currentQuestionIndex + 1}}/{{questions.length}}</text>
|
|
</view>
|
|
</view>
|
|
|
|
+
|
|
|
|
+ <!-- 问题和选项区域 -->
|
|
|
|
+ <view class="question-area">
|
|
|
|
+ <view class="question-importance">
|
|
|
|
+ <!-- <text v-if="currentQuestion.isImportant">重点题</text> -->
|
|
|
|
+ <text class="question-type">{{currentQuestion.questionTypeName}}</text>
|
|
|
|
+ {{currentQuestion.text}}
|
|
|
|
+ </view>
|
|
|
|
|
|
- <view class="options">
|
|
|
|
- <!-- 只渲染非开放问题 (questionType: 1 或 2) 'option-wrong': showResult && (
|
|
|
|
- currentQuestion.questionType === 1 ?
|
|
|
|
- (selectedOption === index && index !== currentQuestion.correctAnswer) :
|
|
|
|
- (selectedOptions.includes(index) && !currentQuestion.correctAnswers.includes(index))
|
|
|
|
- )-->
|
|
|
|
- <view
|
|
|
|
- v-if="currentQuestion.questionType !== 0"
|
|
|
|
- v-for="(option, index) in currentQuestion.options"
|
|
|
|
- :key="index"
|
|
|
|
- class="option-item"
|
|
|
|
- :class="{
|
|
|
|
- 'option-selected': currentQuestion.questionType === 1 ? selectedOption === index : selectedOptions.includes(index),
|
|
|
|
- 'option-correct': showResult && (
|
|
|
|
- currentQuestion.questionType === 1 ? index === currentQuestion.correctAnswer : currentQuestion.correctAnswers.includes(index)
|
|
|
|
- ),
|
|
|
|
-
|
|
|
|
- }"
|
|
|
|
- @click="selectOption(index)">
|
|
|
|
- <!-- 使用字母标识 A、B、C、D、E 等 -->
|
|
|
|
- <!-- <text class="option-prefix">{{ String.fromCharCode(65 + index) }}.</text> -->
|
|
|
|
- <text class="option-text">{{ option.option_text || (typeof option === 'string' ? option : JSON.stringify(option)) }}</text>
|
|
|
|
|
|
+ <!-- 添加图片显示区域,仅在 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>
|
|
</view>
|
|
- </view>
|
|
|
|
|
|
|
|
- <!-- 添加计时器显示 -->
|
|
|
|
- <!-- <view class="timer-container">
|
|
|
|
- <text class="timer-text">本题剩余({{remainingTime}})</text>
|
|
|
|
- </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}} {{"进入下一题"}}<!-- showResult ? '进入下一题' : '提交答案' -->
|
|
|
|
- </button>
|
|
|
|
|
|
+ <view class="options">
|
|
|
|
+ <!-- 渲染非开放问题 (questionType: 1, 2 或 3) 'option-correct': showResult && (
|
|
|
|
+ currentQuestion.questionType === 1 || currentQuestion.questionType === 3 ? index === currentQuestion.correctAnswer : currentQuestion.correctAnswers.includes(index)
|
|
|
|
+ ),-->
|
|
|
|
+ <view
|
|
|
|
+ v-if="currentQuestion.questionType !== 0"
|
|
|
|
+ v-for="(option, index) in currentQuestion.options"
|
|
|
|
+ :key="index"
|
|
|
|
+ class="option-item"
|
|
|
|
+ :class="{
|
|
|
|
+ 'option-selected': currentQuestion.questionType === 1 || currentQuestion.questionType === 3 ? selectedOption === index : selectedOptions.includes(index),
|
|
|
|
+ }"
|
|
|
|
+ @click="selectOption(index)">
|
|
|
|
+ <!-- 使用字母标识 A、B、C、D、E 等 -->
|
|
|
|
+ <!-- <text class="option-prefix">{{ String.fromCharCode(65 + index) }}.</text> -->
|
|
|
|
+ <text class="option-text">{{ option.option_text || (typeof option === 'string' ? option : JSON.stringify(option)) }}</text>
|
|
|
|
+ </view>
|
|
</view>
|
|
</view>
|
|
|
|
+
|
|
|
|
+ <!-- 添加计时器显示 -->
|
|
|
|
+ <!-- <view class="timer-container">
|
|
|
|
+ <text class="timer-text">本题剩余({{remainingTime}})</text>
|
|
|
|
+ </view> -->
|
|
|
|
+
|
|
|
|
+ <!-- 移除底部按钮容器,将在滚动区域外显示 -->
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
+
|
|
|
|
+ <!-- 添加底部空白区域,确保内容不被固定按钮遮挡 -->
|
|
|
|
+ <view class="bottom-space"></view>
|
|
|
|
+ </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}} {{"进入下一题"}}
|
|
|
|
+ </button>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
|
|
@@ -253,7 +260,8 @@
|
|
questionTypeName: q.question_form_name || '单选题',
|
|
questionTypeName: q.question_form_name || '单选题',
|
|
correctAnswers: q.correct_answers || [],
|
|
correctAnswers: q.correct_answers || [],
|
|
difficulty: q.difficulty || 1,
|
|
difficulty: q.difficulty || 1,
|
|
- difficultyName: q.difficulty_name || '初级'
|
|
|
|
|
|
+ difficultyName: q.difficulty_name || '初级',
|
|
|
|
+ imageUrl: q.question_image_url || '' // 添加图片URL字段
|
|
}));
|
|
}));
|
|
} else {
|
|
} else {
|
|
// 处理单个问题
|
|
// 处理单个问题
|
|
@@ -290,11 +298,12 @@
|
|
correctAnswer: data.correctAnswer || 0,
|
|
correctAnswer: data.correctAnswer || 0,
|
|
isImportant: data.is_system || false,
|
|
isImportant: data.is_system || false,
|
|
explanation: data.explanation || '',
|
|
explanation: data.explanation || '',
|
|
- questionType: data.question_form, // 1-单选题,2-多选题
|
|
|
|
|
|
+ questionType: data.question_form, // 1-单选题,2-多选题,3-看图答题
|
|
questionTypeName: data.question_form_name || '单选题',
|
|
questionTypeName: data.question_form_name || '单选题',
|
|
correctAnswers: data.correct_answers || [],
|
|
correctAnswers: data.correct_answers || [],
|
|
difficulty: data.difficulty || 1,
|
|
difficulty: data.difficulty || 1,
|
|
- difficultyName: data.difficulty_name || '初级'
|
|
|
|
|
|
+ difficultyName: data.difficulty_name || '初级',
|
|
|
|
+ imageUrl: data.question_image_url || '' // 添加图片URL字段
|
|
};
|
|
};
|
|
|
|
|
|
// 添加到问题列表
|
|
// 添加到问题列表
|
|
@@ -379,7 +388,7 @@
|
|
// 否则添加到已选中数组
|
|
// 否则添加到已选中数组
|
|
this.selectedOptions.push(index);
|
|
this.selectedOptions.push(index);
|
|
}
|
|
}
|
|
- } else if (this.currentQuestion.questionType === 1) { // 单选题
|
|
|
|
|
|
+ } else if (this.currentQuestion.questionType === 1 || this.currentQuestion.questionType === 3) { // 单选题或看图答题
|
|
this.selectedOption = index;
|
|
this.selectedOption = index;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -411,7 +420,7 @@
|
|
} else {
|
|
} else {
|
|
this.isAnswerCorrect = sortedSelected.every((value, index) => value === sortedCorrect[index]);
|
|
this.isAnswerCorrect = sortedSelected.every((value, index) => value === sortedCorrect[index]);
|
|
}
|
|
}
|
|
- } else { // 单选题
|
|
|
|
|
|
+ } else { // 单选题或看图答题 (questionType === 1 或 3)
|
|
this.isAnswerCorrect = this.selectedOption === this.currentQuestion.correctAnswer;
|
|
this.isAnswerCorrect = this.selectedOption === this.currentQuestion.correctAnswer;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -484,12 +493,18 @@
|
|
answer: this.openQuestionAnswer,
|
|
answer: this.openQuestionAnswer,
|
|
answerDuration: this.getAnswerDuration() // 添加答题时长
|
|
answerDuration: this.getAnswerDuration() // 添加答题时长
|
|
};
|
|
};
|
|
- } else { // 单选或多选
|
|
|
|
|
|
+ } else if (this.currentQuestion.questionType === 1 || this.currentQuestion.questionType === 3) { // 单选题或看图答题
|
|
|
|
+ answer = {
|
|
|
|
+ questionId: this.currentQuestion.id,
|
|
|
|
+ questionType: this.currentQuestion.questionType,
|
|
|
|
+ answer: this.selectedOption,
|
|
|
|
+ answerDuration: this.getAnswerDuration() // 添加答题时长
|
|
|
|
+ };
|
|
|
|
+ } else { // 多选题
|
|
answer = {
|
|
answer = {
|
|
questionId: this.currentQuestion.id,
|
|
questionId: this.currentQuestion.id,
|
|
questionType: this.currentQuestion.questionType,
|
|
questionType: this.currentQuestion.questionType,
|
|
- answer: this.currentQuestion.questionType === 1 ?
|
|
|
|
- this.selectedOption : this.selectedOptions,
|
|
|
|
|
|
+ answer: this.selectedOptions,
|
|
answerDuration: this.getAnswerDuration() // 添加答题时长
|
|
answerDuration: this.getAnswerDuration() // 添加答题时长
|
|
};
|
|
};
|
|
}
|
|
}
|
|
@@ -536,10 +551,11 @@
|
|
if (this.currentAnswer.questionType === 0) {
|
|
if (this.currentAnswer.questionType === 0) {
|
|
// 开放题直接使用文本答案
|
|
// 开放题直接使用文本答案
|
|
answerContent = this.currentAnswer.answer;
|
|
answerContent = this.currentAnswer.answer;
|
|
- } else if (this.currentAnswer.questionType === 1) {
|
|
|
|
- // 单选题,获取选项ID而不是索引
|
|
|
|
|
|
+ } else if (this.currentAnswer.questionType === 1 || this.currentAnswer.questionType === 3) {
|
|
|
|
+ // 单选题或看图答题,获取选项ID而不是索引
|
|
const selectedIndex = this.currentAnswer.answer;
|
|
const selectedIndex = this.currentAnswer.answer;
|
|
const selectedOption = this.currentQuestion.options[selectedIndex];
|
|
const selectedOption = this.currentQuestion.options[selectedIndex];
|
|
|
|
+ console.log('selectedOption',selectedOption);
|
|
// 使用选项的ID或其他唯一标识符
|
|
// 使用选项的ID或其他唯一标识符
|
|
answerContent = selectedOption.id ? selectedOption.id.toString() : selectedIndex.toString();
|
|
answerContent = selectedOption.id ? selectedOption.id.toString() : selectedIndex.toString();
|
|
} else if (this.currentAnswer.questionType === 2) {
|
|
} else if (this.currentAnswer.questionType === 2) {
|
|
@@ -839,6 +855,7 @@
|
|
background-color: #ffffff;
|
|
background-color: #ffffff;
|
|
display: flex;
|
|
display: flex;
|
|
flex-direction: column;
|
|
flex-direction: column;
|
|
|
|
+ overflow: hidden; /* 防止内容溢出 */
|
|
}
|
|
}
|
|
|
|
|
|
.header {
|
|
.header {
|
|
@@ -1062,14 +1079,13 @@
|
|
|
|
|
|
.bottom-button-container {
|
|
.bottom-button-container {
|
|
position: fixed;
|
|
position: fixed;
|
|
- bottom: 30px;
|
|
|
|
- left:7%;
|
|
|
|
|
|
+ bottom: 50px;
|
|
|
|
+ left: 5%;
|
|
right: 0;
|
|
right: 0;
|
|
- background-color: #ffffff;
|
|
|
|
- /* border-top: 1px solid #e0e0e0; */
|
|
|
|
padding: 20rpx;
|
|
padding: 20rpx;
|
|
display: flex;
|
|
display: flex;
|
|
justify-content: center;
|
|
justify-content: center;
|
|
|
|
+ z-index: 10;
|
|
}
|
|
}
|
|
|
|
|
|
.bottom-button-wrapper {
|
|
.bottom-button-wrapper {
|
|
@@ -1374,4 +1390,32 @@
|
|
color: #333;
|
|
color: #333;
|
|
min-width: 30rpx;
|
|
min-width: 30rpx;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ /* 新增的图片显示样式 */
|
|
|
|
+ .question-image-container {
|
|
|
|
+ width: 100%;
|
|
|
|
+ margin: 20rpx 0;
|
|
|
|
+ display: flex;
|
|
|
|
+ justify-content: center;
|
|
|
|
+ align-items: center;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .question-image {
|
|
|
|
+ width: 100%;
|
|
|
|
+ max-width: 600rpx;
|
|
|
|
+ border-radius: 10rpx;
|
|
|
|
+ box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* 添加滚动视图样式 */
|
|
|
|
+ .content-scroll {
|
|
|
|
+ flex: 1;
|
|
|
|
+ height: calc(100vh - 130px); /* 减去底部按钮的高度 */
|
|
|
|
+ overflow-y: auto;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* 添加底部空白区域,防止内容被固定按钮遮挡 */
|
|
|
|
+ .bottom-space {
|
|
|
|
+ height: 130px; /* 与底部按钮高度一致 */
|
|
|
|
+ }
|
|
</style>
|
|
</style>
|