开发完错题本

This commit is contained in:
田岩
2025-08-30 20:31:58 +08:00
parent 859248fc6a
commit 05b89f91ca
20 changed files with 396 additions and 232 deletions
+9 -4
View File
@@ -97,13 +97,18 @@ export default function request({
const res = response.data
if (res?.rtnCode === '0000') {
return resolve(res)
} else if (toastErrors) {
// common.msg(res?.message)
} else if (res?.rtnCode === '0001') { // 为前后端约定不公共拦截的码值(王洋洋20250830定)
return reject(res)
} else if (res?.rtnCode === '0002' && res?.message) {
if (toastErrors) {
common.msg(res.message)
}
return reject(response)
}
//到这里下面全是异常的处理
if (suppressErrors) { // 静默的接口,报错也不处理,因为下面有公共处理
return reject()
return reject(response)
}
if (!res) {
common.msg("系统异常.")
+1 -1
View File
@@ -37,7 +37,7 @@ export const queryMistakesAnswerByMisId = (data) => {
return request({
url: base_url + '/traMistakesCollection/queryMistakesAnswerByMisId ',
method: 'post',
toastErrors: true,
toastErrors: false,
data
});
};
+36 -23
View File
@@ -51,13 +51,13 @@
<view class="back-icon"></view>
</view>
<view class="fl1"></view>
<view class="num-item" @click="collect_click(form.collectId)">
<image
class="collect-icon"
:src="form.collectId ? collectedImg : notCollectedImg"
mode="widthFix"
></image>
</view>
<view class="num-item" @click="collect_click(form.collectId)">
<image
class="collect-icon"
:src="form.collectId ? collectedImg : notCollectedImg"
mode="widthFix"
></image>
</view>
</view>
</view>
<view class="body-box">
@@ -92,15 +92,18 @@
</view>
</scroll-view>
<view class="btn-box btn-box-height font_pf">
<template v-if="[0, 1].includes(tabAct)" >
<uv-button
type="primary"
@click="common.navigateTo(`/pages/course/study?crsId=${crsId}&isPreview=${isPreview}&imgId=${form.imgId}`)"
>
</uv-button>
<uv-button type="primary" :disabled="isPreview === 'preview'" @click="goto_practice()">去练习</uv-button>
<uv-button type="primary" :disabled="isPreview === 'preview'" @click="goto_examination()">去考试</uv-button>
<template v-if="[0, 1].includes(tabAct)">
<view class="fl1">
<uv-button type="primary" @click="goto_study()">去学习</uv-button>
</view>
<view class="fl1" @click="goto_practice()">
<uv-button type="primary" :disabled="practiceButtonDisabled" ></uv-button>
</view>
<view class="fl1" @click="goto_examination()">
<uv-button type="primary" :disabled="examinationButtonDisabled" >
去考试
</uv-button>
</view>
</template>
<template v-if="tabAct === 2">
<uv-button
@@ -133,7 +136,6 @@
const statusBarHeight = uni.getSystemInfoSync().statusBarHeight;
// tab栏
const tabList = ref([{ name: '课程介绍' }, { name: '知识点' }, { name: '评价' }]);
const commentRef = ref(null);
const form = ref({});
const crsId = ref('');
@@ -141,6 +143,9 @@
const isPreview = ref(''); // 记录是否是预览
const tabAct = ref(0);
const scrollTop = ref(0);
const practiceButtonDisabled = computed(() => isPreview.value === 'preview' || form.value.examStat === '02');
const examinationButtonDisabled = computed(() => isPreview.value === 'preview' || form.value.examStat !== '00');
const tabSwitch = (item) => {
tabAct.value = item.index;
};
@@ -150,7 +155,7 @@
commentRef.value?.getData();
}
};
const getData = async () => {
const { body } = await getCourseDetailApi({
crsId: crsId.value
@@ -175,8 +180,7 @@
const opacity = Math.min(1, (scrollTop.value - 20) / 80);
return `rgba(255,255,255,${opacity})`;
});
const scroll_fun = (e) => {
scrollTop.value = e.detail.scrollTop;
};
@@ -184,10 +188,12 @@
const swiper_change = (res) => {
tabAct.value = res.detail.current;
};
// 去考试
const goto_examination = async () => {
if(isPreview.value === 'preview') return common.msg('预览课程不允许考试');
if (isPreview.value === 'preview') return common.msg('预览课程不允许考试');
if (form.value.examStat === '01') return common.msg('该课程下暂无试题');
if (form.value.examStat === '02') return common.msg('该课程下的试题未设置考试规则');
common.loading();
startExamByCrs({
crsId: crsId.value
@@ -204,9 +210,16 @@
common.hideLoading();
});
};
// 去学习
const goto_study = async () => {
common.navigateTo(
'/pages/course/study?crsId=' + crsId.value + '&isPreview=' + isPreview.value + '&imgId=' + form.value.imgId
);
};
// 去练习
const goto_practice = async () => {
if(isPreview.value === 'preview') return common.msg('预览课程不允许练习');
if (isPreview.value === 'preview') return common.msg('预览课程不允许练习');
if (form.value.examStat !== '00') return common.msg('该课程下暂无试题');
common.loading();
startPracticeByCrs({
crsId: crsId.value
@@ -97,11 +97,12 @@
};
// 跳转到详情
const click_list_item = (list_item) => {
console.log('list_item', list_item);
const examLenTm = 666;
const papersName = item.value.examName;
common.navigateTo(
`/pages/examination/result?execId=${list_item.execId}&examLenTm=${examLenTm}&papersName=${papersName}&mode=record`
`/pages/examination/result?execId=${list_item.execId}&papersName=${papersName}&mode=record`
);
};
</script>
@@ -43,7 +43,6 @@
</template>
<script setup>
console.log('反馈组件');
import { ref, reactive, computed, onMounted, onUnmounted, nextTick } from 'vue';
import { optionErrorIcon } from '@/common/imgSvg';
import { saveTraQnsFeedback } from '@/api/examination.js';
@@ -130,7 +129,6 @@
// 组件挂载时设置监听
let removeListener = () => {};
onMounted(() => {
console.log('组件挂载时设置监听');
removeListener = setupKeyboardHeightListener((height) => {
feedback_popup_bottom.value = `${height}px`;
});
+7 -5
View File
@@ -223,6 +223,7 @@
// 倒计时结束
const finish = (item) => {
console.log('倒计时结束自动交卷');
};
@@ -293,7 +294,7 @@
};
}
};
// 初始化时检查
onLoad(() => {
const examination = getPageCache('examination');
@@ -303,7 +304,6 @@
}
// 记录起始时间
examinationStartTime = new Date().getTime();
paperData.crsId = examination.crsId;
paperData.execId = examination.execId;
paperData.examId = examination.examId;
@@ -432,7 +432,10 @@
});
console.log('提交的', answerDtoList);
console.log('answerDtoList', answerDtoList);
// 计算当前时间与开始时间的毫秒差值,再转换为整数秒
const examLenTm = Math.floor((new Date().getTime() - examinationStartTime) / 1000);
dialogRef.value.close();
console.log('examLenTm', examLenTm);
common.loading('正在提交');
// 这里通过是否存在examId来判断是考试中心的考试还是课程的考试
let func;
@@ -442,14 +445,14 @@
papersId: paperData.papersId,
examId: paperData.examId,
execId: paperData.execId,
examLenTm: 1200,
examLenTm: examLenTm,
answerDtoStr: JSON.stringify(answerDtoList)
});
} else {
func = commitCrsExam({
papersId: paperData.papersId,
execId: paperData.execId,
examLenTm: 1200,
examLenTm: examLenTm,
answerDtoStr: JSON.stringify(answerDtoList)
});
}
@@ -458,7 +461,6 @@
// 判断是否需要查分
if (res.body.flagQuery === 'Y') {
// 需要查分
const examLenTm = 678;
common.redirectTo(
`/pages/examination/result?execId=${res.body.execId}&examLenTm=${examLenTm}&papersName=${paperData.papersName}&papersId=${paperData.papersId}&mode=${mode}&crsId=${paperData.crsId}`
);
+114 -81
View File
@@ -24,6 +24,9 @@
<text v-if="pass_status === -1" class="no-pass">{{ result.examGrade }}</text>
<text v-if="pass_status === 1" class="pass">{{ result.examGrade }}</text>
</view>
<view class="bottom" v-if="result.passGrade">
<text class="">通过分数{{ result.passGrade }}</text>
</view>
<view class="bottom">
<text v-if="pass_status === -1">失败乃成功之母继续努力</text>
<text v-if="pass_status === 1">考的不错啊继续加油</text>
@@ -78,7 +81,7 @@
</view>
<view class="time">
<!-- 12 15 -->
时长{{ result.examLenTm }}
时长{{ formatSecondsToText(result.examLenTm) }}
</view>
<view class="fl1"></view>
<view class="examination" @click="goExamRanking" v-if="result.mode === 'examination'">
@@ -101,7 +104,7 @@
<swiper-item v-for="(group, groupIndex) in groupedTopicList" :key="groupIndex">
<uv-grid :col="5" class="sheet_table" @click="sheet_click">
<uv-grid-item v-for="(item, index) in group" :key="index">
<view class="circle">
<view class="circle" :class="{ current: index === sheet_index }">
{{ groupIndex * 10 + index + 1 }}
</view>
</uv-grid-item>
@@ -110,13 +113,17 @@
</swiper>
<view class="swiper-dots"></view>
</view>
<!-- 获取答题结果时候的图片 -->
<view class="loading-pass-image-div" v-if="pass_status === 0">
<image src="@/static/images/examination/getting_robot.png" mode="widthFix" class="img"></image>
<view class="tip">你的等待会有更精确的结果要耐心哦~</view>
</view>
<view class="" :id="'id_' + index" :class="getStatusClass(index)" v-for="(item, index) in topicList">
<view
class=""
v-show="index === sheet_index"
:class="getStatusClass(index)"
v-for="(item, index) in topicList"
>
<Subject :item="item" mode="settlement" :clearResult="false" :isPreview="true"></Subject>
</view>
</view>
@@ -137,11 +144,12 @@
execId: '',
papersId: '',
mode: '',
passGrade: '',
papersName: '',
examLenTm: '',
examGrade: ''
});
const sheet_swiper_change = (event) => {
sheet_swiper_index.value = event.detail.current;
};
@@ -161,25 +169,27 @@
return groups;
});
const scrollTop = ref(0);
const topic = ref();
const sheet_index = ref(-1);
// 答题卡点击
const sheet_click = (index) => {
scrollTop.value = index * 200;
// console.log('topicList', topicList[index]);
// topic.value = topicList[index]
sheet_index.value = index;
// scrollTop.value = index * 200;
};
const scroll = (event) => {
};
const scroll = (event) => {};
// 跳转到去考试页面
const goExamRanking = () => {
// 首先判断是课程跳入还是考试中心跳入
if(result.crsId !== '') {
common.navigateTo('/pages/examRanking/index?crsId=' + result.crsId)
if (result.crsId !== '') {
common.navigateTo('/pages/examRanking/index?crsId=' + result.crsId);
} else {
common.navigateTo('/pages/examRanking/index?papersId=' + result.papersId)
common.navigateTo('/pages/examRanking/index?papersId=' + result.papersId);
}
}
};
const getStatusClass = (index) => {
const remainder = index % 3;
@@ -190,53 +200,59 @@
const animationfinish = (event) => {
console.log('event', event);
};
// 定义请求计数器和定时器引用
const requestCount = ref(0);
const timerId = ref(null);
const get_result = () => {
// 重置计数器(首次调用时)
if (requestCount.value === 0) {
requestCount.value = 0;
}
// 检查是否已达到最大请求次数
if (requestCount.value >= 15) {
console.log('已达到最大请求次数(15次),停止请求');
return;
}
timerId.value = setTimeout(() => {
// 每次请求前计数器+1
requestCount.value++;
queryPaperExamScore({
execId: result.execId
}).then(({ body }) => {
console.log(`${requestCount.value}次请求返回`, body);
if (body.isWait === 'Y') {
// 未完成且未达上限,继续请求
if (requestCount.value < 15) {
get_result();
} else {
console.log('已达到最大请求次数,停止等待');
}
} else if (body.isWait === 'N') {
// 完成请求,处理结果
pass_status.value = body.examResult === 'P' ? 1 : -1;
result.examGrade = body.examGrade;
topicList.push(...body.qnsInfoVo);
}
}).catch(err => {
console.error('请求失败', err);
// 请求失败也计入次数,避免无限重试
if (requestCount.value < 15) {
get_result();
}
});
}, 2000);
// 重置计数器(首次调用时)
if (requestCount.value === 0) {
requestCount.value = 0;
}
// 检查是否已达到最大请求次数
if (requestCount.value >= 15) {
console.log('已达到最大请求次数(15次),停止请求');
return;
}
timerId.value = setTimeout(() => {
// 每次请求前计数器+1
requestCount.value++;
queryPaperExamScore({
execId: result.execId
})
.then(({ body }) => {
console.log(`${requestCount.value}次请求返回`, body);
if (body.isWait === 'Y') {
// 未完成且未达上限,继续请求
if (requestCount.value < 15) {
get_result();
} else {
console.log('已达到最大请求次数,停止等待');
}
} else if (body.isWait === 'N') {
// 完成请求,处理结果
pass_status.value = body.examResult === 'P' ? 1 : -1;
result.examGrade = body.examGrade;
result.passGrade = body.passGrade || '';
if (result.examLenTm === undefined) {
result.examLenTm = body.examLenTm;
}
topicList.push(...body.qnsInfoVo);
}
})
.catch((err) => {
console.error('请求失败', err);
// 请求失败也计入次数,避免无限重试
if (requestCount.value < 15) {
get_result();
}
});
}, 2000);
};
// 初始化时检查
@@ -246,23 +262,55 @@
result.papersName = e.papersName;
result.examLenTm = e.examLenTm;
result.mode = e.mode || '';
result.papersId = e.papersId;
get_result();
});
// 页面卸载时清除定时器,终止请求
onUnload(() => {
if (timerId.value) {
clearTimeout(timerId.value);
timerId.value = null;
}
if (timerId.value) {
clearTimeout(timerId.value);
timerId.value = null;
}
});
const formatSecondsToText = (milliseconds) => {
console.log('milliseconds', milliseconds);
if (milliseconds === undefined) return '--';
// 尝试将输入转换为数字(处理字符串形式的数字)
const num = Number(milliseconds);
// 验证是否为有效数字且非负数
if (isNaN(num) || num < 0) {
return '0秒';
}
// 将毫秒转换为秒(取整)
const seconds = num;
// 计算小时、分钟、秒
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
const secs = Math.floor(seconds % 60);
console.log('secs', secs);
// 存储各部分文本
const parts = [];
if (hours > 0) {
parts.push(`${hours}小时`);
}
if (minutes > 0) {
parts.push(`${minutes}`);
}
// 确保至少显示秒数,即使为0
parts.push(`${secs}`);
// 拼接结果
return parts.join('');
};
</script>
<style scoped lang="scss">
$bg-margin-left: 30rpx;
.current {
background-color: rgba(0, 102, 255, 0.6);
border-color: #0066ff;
color: #ffffff;
}
.scroll-Y {
// max-height: calc(100vh - var(--status-bar-height) - 70rpx - 70rpx - 40rpx - 64rpx - 68rpx - 60rpx);
height: calc(100vh - var(--status-bar-height) - 70rpx - 10rpx);
@@ -330,25 +378,10 @@
}
}
.sticky {
}
.sheet_table_div_fixed {
position: absolute;
top: calc(var(--status-bar-height) + 70rpx);
left: 0;
z-index: 600;
height: 230rpx;
width: calc(100% - 56rpx);
margin: 0 28rpx 0 28rpx;
background-color: #fff;
// opacity: .5;
}
.sheet_table_div {
position: sticky;
left: 0;
top: 0;
top: -2rpx;
width: 100%;
z-index: 600;
background-color: #fff;
-1
View File
@@ -7,7 +7,6 @@
</view>
<view class="title font_pf">考试记录</view>
</view>
<view class="detail-body">
<examRecordList ref="listItemRef"></examRecordList>
@@ -208,7 +208,7 @@
border: 2rpx solid #ffa150;
font-family: PingFangSC;
font-weight: 500;
font-size: 23rpx;
font-size: 22rpx;
color: #ffa150;
display: flex;
justify-content: center;
@@ -220,12 +220,12 @@
display: flex;
font-family: PingFangSC;
font-weight: 400;
font-size: 24rpx;
font-size: 22rpx;
color: #666;
margin-bottom: 16rpx;
line-height: 23rpx;
line-height: 24rpx;
flex-wrap: nowrap;
height: 23rpx;
height: 24rpx;
overflow: hidden;
}
}
@@ -256,11 +256,11 @@
.time_div {
font-family: Arial;
font-weight: 400;
font-size: 23rpx;
font-size: 22rpx;
color: #666;
line-height: 23rpx;
line-height: 24rpx;
flex-wrap: nowrap;
height: 23rpx;
height: 24rpx;
overflow: hidden;
}
@@ -268,13 +268,13 @@
display: flex;
font-family: PingFangSC;
font-weight: 400;
font-size: 23rpx;
font-size: 22rpx;
color: #666;
margin-bottom: 23rpx;
margin-bottom: 22rpx;
line-height: 23rpx;
line-height: 24rpx;
flex-wrap: nowrap;
height: 23rpx;
height: 24rpx;
overflow: hidden;
}
}
+1
View File
@@ -82,6 +82,7 @@
</view>
<TouchBtn class="talk-btns" @uploadVoice="uploadRecordNow" @submitAnswer="submitAnswerNow"
@startRecord="startRecordCallback" :loadingText="sendLoadingText" :isLoading="!answerIsOver"
:adjustPosition="true"
:isDisabled="false" />
<!-- 反馈组件 -->
<Feedback ref="feedbackRef" @feedbackAnswer="feedbackAnswer"></Feedback>
+2 -2
View File
@@ -16,7 +16,7 @@
:readonly="true"
></uv-input>
</view>
<view class="message_div">
<view class="message_div" @click="common.navigateTo('/pages/messageNotification/index')">
<image src="@/static/images/index/message_b.png" class="message_img"></image>
<view class="message_text">消息</view>
<view class="message_num message_num_font">30</view>
@@ -39,7 +39,7 @@
:suffixIconStyle="suffixIconStyle"
:readonly="true"
></uv-input>
<view class="message_div">
<view class="message_div" @click="common.navigateTo('/pages/messageNotification/index')">
<image src="@/static/images/index/message.png" class="message_img"></image>
<view class="message_text">消息</view>
<view class="message_num message_num_font">30</view>
@@ -143,27 +143,26 @@
.time_div {
font-family: PingFangSC;
font-weight: 400;
font-size: 23rpx;
font-size: 22rpx;
color: #666;
line-height: 23rpx;
line-height: 24rpx;
flex-wrap: nowrap;
height: 23rpx;
height: 24rpx;
overflow: hidden;
white-space: nowrap;
}
.people_progress_div {
display: flex;
font-family: PingFangSC;
font-weight: 400;
font-size: 23rpx;
font-size: 22rpx;
color: #666;
margin-bottom: 23rpx;
white-space: nowrap;
line-height: 23rpx;
line-height: 24rpx;
flex-wrap: nowrap;
height: 23rpx;
overflow: hidden;
height: 24rpx;
// overflow: hidden;
}
}
}
+4 -2
View File
@@ -97,7 +97,7 @@
:src="passTheExamIcon(item.isFinishStudy === '02' ? '#0066FF' : '#999999')"
></image>
<view class="button_text" :class="item.isFinishStudy === '02' ? 'success' : 'error'">
完成
完成
</view>
</template>
<template v-if="item.isFinishExam !== '01'">
@@ -303,7 +303,9 @@
.circle_div {
width: 20rpx;
height: 20rpx;
border-radius: 100%;
border-radius: 50%;
overflow: hidden;
box-sizing: border-box;
}
.line_div {
height: calc(100% - 20rpx);
+15 -6
View File
@@ -197,6 +197,7 @@
const submitProblem = (answer) => {
console.log('答题内容', answer);
console.log('答单题', topic);
common.loading('答题中');
practiceAnswer({
exrId: paperData.exrId,
@@ -245,7 +246,11 @@
judgeResultStatus && // 条件1.答题正确
topic.value.qnsTyp !== 'ES' // 问答题答对打答错都不切换
) {
questionNumber.value++;
nextTick(() => {
setTimeout(() => {
questionNumber.value++;
}, 200);
});
} else {
console.log('为什么不跳转2', judgeResultStatus);
console.log('为什么不跳转3', topic.value.qnsTyp !== 'ES');
@@ -365,10 +370,12 @@
// 中途退出
dialogRef.value.close();
common.loading();
await practiceCommit({ exrId: paperData.exrId, examLenTm: practiceTime.value, stat: 'U' });
try{
await practiceCommit({ exrId: paperData.exrId, examLenTm: practiceTime.value, stat: 'U' });
common.navigateBack();
}catch(e){
}
common.hideLoading();
await nextTick();
common.navigateBack();
} else if (key === 'revert') {
// 返回
dialogRef.value.close();
@@ -391,9 +398,11 @@
// 交卷按钮点击,打开交卷确认框
const hand_in_paper_button_click = async () => {
console.log('交卷按钮');
const stat = 'P'
const stat = 'P';
// 都做完弹窗了,产品说改成跳页,说客户觉得奇怪
common.redirectTo(`/pages/practice/result?name=${paperData.name}&exrId=${paperData.exrId}&crsId=${paperData.crsId}&examLenTm=${practiceTime.value}&stat=${stat}`);
common.redirectTo(
`/pages/practice/result?name=${paperData.name}&exrId=${paperData.exrId}&crsId=${paperData.crsId}&examLenTm=${practiceTime.value}&stat=${stat}`
);
// 完成
// dialogRef.value.open({
// // type: 'complete',
+2 -1
View File
@@ -31,7 +31,7 @@
</view>
<view class="title-note">
考试时长
<text class="bold">{{ detailData.limitTm }}</text>
<text class="bold">{{ detailData.limitTm / 60 }}</text>
分钟
</view>
<view class="title-table">
@@ -154,6 +154,7 @@
}, 0)
);
const goto_examination = async () => {
if(detailData.limitTyp === 'SG' && detailData.examStatText === 'Y') return common.msg('考试已完成');
common.loading();
startTraExamPapersInfo({
examId: detailData.examId
+108 -74
View File
@@ -42,7 +42,12 @@
<view class="content">
<view class="expose_shadow"></view>
<scroll-view :scroll-y="true" class="scroll-Y" :show-scrollbar="false" :refresher-threshold="0">
<view class="" v-if="item === '00'">加载中</view>
<view class="" v-if="item === '01'">加载失败</view>
<view class="" v-if="item === '02'">加载失败</view>
<Subject
v-else
:item="item"
:mode="mode"
:isPreview="item.isPreview"
@@ -93,32 +98,29 @@
const dialogRef = ref(null);
const touchBtnRef = ref(null);
const mode = ref('practice'); // 考试 examination 练习practice
const paperData = reactive({
name: '' // 名称
}); // 试卷信息
const topicList = reactive([]); // 问题列表
const storageIdList = ref([]); // 所有题ID列表
const storageIdDict = ref({}); // 所有题ID为键的字典
const popup_input_bottom = ref('0px');
const questionNumber = ref(0); // 题号
// 根据课程ID获取课程的题目 undefined为没有, 00为加载中, 02为加载失败
const topic = computed({
get: () => topicList[questionNumber.value],
set: (val) => (topicList[questionNumber.value] = val)
});
const showTouchBtn = computed(() => {
return topic.value?.qnsTyp === 'ES';
});
// 下面语音组件的禁用状态判断
const touchIsDisabled = computed(() => {
console.log('下面语音组件的禁用状态判断', topic.value?.es_status !== '' && topic.value?.es_status !== undefined);
return topic.value?.es_status !== '' && topic.value?.es_status !== undefined;
});
const touchIsDisabled = computed(() => topic.value?.es_status !== '' && topic.value?.es_status !== undefined);
const progress = computed(() => {
// 计算进度百分比(保留两位小数)
@@ -147,13 +149,12 @@
const transition = (event) => {
if (isTriggered.value) return;
const dx = event.detail.dx;
if (dx > 50 && dx < 200 && isLastTopic.value && ['P', 'U'].includes(topic.value.judgeResult)) {
if (dx > 90 && dx < 250 && isLastTopic.value && ['P', 'U'].includes(topic.value.judgeResult)) {
// 如果是最后一题并且右滑动大于50,并且这题已经答了,就触发练习完成
isTriggered.value = true;
hand_in_paper_button_click();
}
};
const subject_click = (type, params) => {
if (type === 'feedback') {
// 反馈
@@ -220,29 +221,32 @@
topic.value.judgeResult = traQnsInfoVo.judgeResult; // 正确答案字符串分割
const judgeResultStatus = traQnsInfoVo.judgeResult === 'P'; // P为正确U为错误
// 加载下一题
addProblem(questionNumber.value + 1)
// if (!addProblem()) {
// // 返回false说明到了最后一题
// console.log('最后一题', topic.value.qnsTyp, !judgeResultStatus);
// if (topic.value.qnsTyp === 'ES' || !judgeResultStatus) {
// // 最后一题是问答题,或者答错了,都不自动弹出
// return;
// } else {
// await hand_in_paper_button_click();
// }
// } else {
// // 自动切换下一题的条件
// if (
// judgeResultStatus && // 条件1.答题正确
// topic.value.qnsTyp !== 'ES' // 问答题答对打答错都不切换
// ) {
// questionNumber.value++;
// } else {
// console.log('为什么不跳转2', judgeResultStatus);
// console.log('为什么不跳转3', topic.value.qnsTyp !== 'ES');
// }
// }
if (!addProblem(questionNumber.value + 1)) {
// 返回false说明到了最后一题
console.log('最后一题', topic.value.qnsTyp, !judgeResultStatus);
if (topic.value.qnsTyp === 'ES' || !judgeResultStatus) {
// 最后一题是问答题,或者答错了,都不自动弹出
return;
} else {
await hand_in_paper_button_click();
}
} else {
addRequestProblem(questionNumber.value + 1);
// 自动切换下一题的条件
if (
judgeResultStatus && // 条件1.答题正确
topic.value.qnsTyp !== 'ES' // 问答题答对打答错都不切换
) {
nextTick(() => {
setTimeout(() => {
questionNumber.value++;
}, 200);
});
} else {
console.log('为什么不跳转2', judgeResultStatus);
console.log('为什么不跳转3', topic.value.qnsTyp !== 'ES');
}
}
})
.catch(() => {
common.hideLoading();
@@ -283,6 +287,7 @@
return Promise.reject(error);
});
};
// 录音组件提交
const touchBtnSubmit = (type, submitObj) => {
const old_text = touchBtnRef.value?.clearinputText(); // 清除发送框数据
@@ -316,27 +321,77 @@
};
}
};
// 添加一道题
const addProblem = async (index, isLoading) => {
// index 要加载的题号 isLoading是否显示loading
if(index < topicList.length) return true; // 说明此题已经加载
if (topicList.length >= storageIdList.value.length) return false; // 说明已经
if (isLoading) common.loading('加载题目中');
// 添加一道题
const addProblem = async (index) => {
// index 要加载的题号
if (index < topicList.length) return true; // 说明此题已经加载
if (topicList.length >= storageIdList.value.length) return false; // 说明已经加载所有题了
const id = storageIdList.value[index]; // 找到id
if (storageIdDict.value[id] === undefined) {
//尚未加载(几乎不可能)
return true;
} else if (storageIdDict.value[id].state === '00') {
//加载中
} else if (storageIdDict.value[id].state === '01') {
// 已经加载
// console.log('增加已经加载的数据', storageIdDict.value[id].topic);
topicList.push(storageIdDict.value[id].topic);
return true;
} else if (storageIdDict.value[id].state === '02') {
//加载失败
}
topicList.push(storageIdDict.value[id].state);
return true;
};
// 网络加载题,并且放在
const addRequestProblem = async (index, success = () => {}) => {
const id = storageIdList.value[index];
const preload = () => {
nextTick(() => {
// 最多只预加载当前题号的后两道题(questionNumber.value是当前题号)
// 修正索引判断:确保 index + 1 是有效的数组索引(< 数组长度)
if (index + 1 === storageIdList.value.length) return; // 防止下标越界
if (index + 1 > questionNumber.value + 2) return; // 防止加载太多
const last_id = storageIdList.value[index + 1];
// 判断是否加载
if (last_id in storageIdDict.value) {
return;
}else {
addRequestProblem(index + 1, success);
}
});
};
if (storageIdDict.value[id] && storageIdDict.value[id].state === '01') {
preload();
return;
}
storageIdDict.value[id] = { state: '00' };
queryMistakesAnswerByMisId({ misId: id })
.then(({ body }) => {
console.log('加载了一道题', body);
topicList.push({
const topic_item = {
...body,
isPreview: false,
clearResult: true,
es_status: '', // 预设一下问答题的状态,'' 空为没有 00 转圈 01 播放,其他暂定
my_answer: []
});
};
storageIdDict.value[id] = {
state: '01',
topic: topic_item
};
success(topic_item);
preload();
})
.catch(() => {
storageIdDict.value[id] = { state: '02' };
})
.finally(() => {
if (isLoading) common.hideLoading();
// if (isLoading) common.hideLoading();
});
};
// 初始化时检查
@@ -347,14 +402,19 @@
}
paperData.name = correct.name;
storageIdList.value = correct.list;
// 记录练习起始时间
setupKeyboardHeightListener((height) => {
popup_input_bottom.value = `${height}px`;
});
setTimeout(() => {
addProblem(0, true);
addRequestProblem(0, () => {
addProblem(0);
});
// addProblem(0, true);
}, 10);
});
const result_click = async ({ key }) => {
isTriggered.value = false; // 恢复
if (key === 'return') {
@@ -392,34 +452,8 @@
// 交卷按钮点击,打开交卷确认框
const hand_in_paper_button_click = async () => {
console.log('交卷按钮');
common.loading();
try {
await practiceCommit({ exrId: paperData.exrId, stat: 'P' });
} catch (e) {}
common.hideLoading();
console.log('点击交卷', paperData);
// 完成
dialogRef.value.open({
// type: 'complete',
title: '恭喜你,已完成全部练习!',
buttonList: [
{
key: 'goto_test',
name: '去考试',
style: style_button_1
},
{
key: 'again',
name: '重新练',
style: style_button_2
},
{
key: 'return',
name: '返回',
style: style_button_2
}
]
});
const stat = 'P';
common.redirectTo(`/pages/wrongQuestionRecord/result?stat=${stat}`);
};
// 中途退出
+75 -4
View File
@@ -1,11 +1,82 @@
<template>
<view class="max_page">
<image src="@/static/images/common/wc.png" class="img"></image>
<image src="@/static/images/common/wc.png" class="show_img"></image>
<view class="show_msg">完成错题练习</view>
<view class="fl1"></view>
<view class="show_button">
<uv-button
type="primary"
class="button"
color="#FFFFFF"
:throttleTime="100"
text="返回"
@click="back_page"
:custom-style="customStyle2"
></uv-button>
</view>
</view>
</template>
<script>
<script setup>
import common from '@/common/common';
const customStyle1 = {
borderRadius: '12rpx',
color: '#FFFFFF',
fontWeight: '600',
fontSize: '28rpx',
border: '1px solid #E0E0E0',
height: '92rpx'
};
const customStyle2 = {
borderRadius: '12rpx',
color: '#333333',
fontWeight: '600',
fontSize: '28rpx',
border: '1px solid #E0E0E0',
height: '92rpx'
};
const customStyle3 = {
color: '#333333',
fontWeight: '600',
fontSize: '28rpx',
border: 'none',
backgroundColor: '#fff',
height: '92rpx'
};
//
const back_page = () => {
common.navigateBack();
};
</script>
<style>
</style>
<style scoped lang="scss">
.max_page {
display: flex;
align-items: center;
flex-direction: column;
}
.show_img {
margin-top: 300rpx;
width: 231rpx;
height: 231rpx;
}
.show_msg {
margin-top: 38rpx;
font-weight: 700;
font-size: 46rpx;
color: #000000;
line-height: 62rpx;
text-align: center;
font-style: normal;
}
.show_button {
width: 80%;
margin-bottom: 180rpx;
.button:nth-child(2) {
margin-top: 38rpx;
margin-bottom: 38rpx;
}
}
</style>
+1 -3
View File
@@ -68,7 +68,7 @@ export const useAudioStore = defineStore('audioStore', {
// 音频可以播放时触发(此时通常能获取到时长)
this.audioInstance.onCanplay(() => {
// 尝试获取时长(部分环境需要延迟一点)
console.log('尝试获取时长(部分环境需要延迟一点)');
// console.log('尝试获取时长(部分环境需要延迟一点)');
setTimeout(() => {
const duration = this.audioInstance.duration || 0;
console.log('尝试获duration', duration);
@@ -208,7 +208,6 @@ export const useAudioStore = defineStore('audioStore', {
},
// 注册播放完成回调
onAudioEnded(callback) {
console.log('onAudioEnded');
if (typeof callback === 'function') {
this.callbacks.onEnded = callback;
}
@@ -216,7 +215,6 @@ export const useAudioStore = defineStore('audioStore', {
// 注册播放错误回调
onAudioError(callback) {
console.log('注册播放错误回调');
if (typeof callback === 'function') {
this.callbacks.onError = callback;
}