开发完错题本

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
+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>