修改bug

This commit is contained in:
田岩
2025-09-05 15:59:18 +08:00
parent f5da8fbff4
commit 25f01d49bb
14 changed files with 231 additions and 207 deletions
+3 -3
View File
@@ -15,7 +15,7 @@ VITE_APP_BASE_API_Url = 'https://aitstest.jlbank.com.cn:7001'
# h5专用地址
VITE_APP_BASE_H5_API_Url = 'https://aitstest.jlbank.com.cn:7001'
VITE_APP_BASE_H5_API_Url = 'https://aitstest.jlbank.com.cn:7002'
# VITE_APP_BASE_H5_API_Url = 'https://aitstest.jlbank.com.cn:7002'
# dev
@@ -27,8 +27,8 @@ VITE_APP_BASE_H5_API_Url = 'https://aitstest.jlbank.com.cn:7001'
# VITE_APP_BASE_H5_API_Url = 'http://25.18.122.78:9786'
# 任东
VITE_APP_BASE_H5_API_Url_TRAAPP = 'http://25.64.16.130:9601'
VITE_APP_BASE_H5_API_Url_TRASTUDY = 'http://25.64.16.130:9602'
#VITE_APP_BASE_H5_API_Url_TRAAPP = 'http://25.64.16.130:9601'
#VITE_APP_BASE_H5_API_Url_TRASTUDY = 'http://25.64.16.130:9602'
# VITE_APP_BASE_H5_API_Url_TRAEXAM = 'http://25.64.16.140:9604'
# 张建成
+15 -1
View File
@@ -33,6 +33,7 @@ export const queryPaperExamScore = (data) => {
};
// ↑↑↑↑↑↑↑↑↑考试中心考试↑↑↑↑↑↑↑
// ↓↓↓↓↓↓↓↓↓课程考试↓↓↓↓↓↓↓↓
export const startExamByCrs = (data) => {
@@ -83,4 +84,17 @@ export const queryPaperExamRankingList = (data) => {
data
});
};
// 考试过程中提交结果,后端用来缓存(考试中心考试和课程考试共用这个缓存接口)
export const commitPaperCache = (data) => {
return request({
url: base_url + '/traExamPapers/commitPaperCache',
method: 'post',
toastErrors: true,
data
});
};
+12 -1
View File
@@ -40,4 +40,15 @@ export const queryMistakesAnswerByMisId = (data) => {
toastErrors: false,
data
});
};
};
// 根据ID查题
export const queryMistakesCorrectByMisId = (data) => {
return request({
url: base_url + '/traMistakesCollection/queryMistakesCorrectByMisId',
method: 'post',
toastErrors: false,
data
});
};
+5 -6
View File
@@ -17,7 +17,7 @@
<view class="detail-body">
<view class="head-title font_pf">
<view class="title-text">
{{ form.crsName || '' }}
{{form.crsName}}
</view>
<view class="title-num">
<view class="num-item">
@@ -75,19 +75,15 @@
></uv-tabs>
</view>
</uv-sticky>
<!-- <swiper class="body-swiper" @change="swiper_change" :current="tabAct"><swiper-item> -->
<view class="course-info" v-if="tabAct === 0">
<introduceVue v-model="form"></introduceVue>
</view>
<!--</swiper-item><swiper-item>-->
<view class="point" v-if="tabAct === 1">
<knowledge v-model="form" @toStudyPrgh="toStudyPrgh"></knowledge>
</view>
<!--</swiper-item><swiper-item>-->
<view class="evaluate" v-if="tabAct === 2 && form">
<comment ref="commentRef" :crsId="crsId" :imgId="form.imgId"></comment>
</view>
<!--</swiper-item></swiper>-->
</view>
</view>
</scroll-view>
@@ -381,7 +377,9 @@
padding-top: 36rpx;
padding-left: 42rpx;
padding-bottom: 24rpx;
min-height: 158rpx;
// overflow: hidden;
justify-content: space-between;
}
@@ -390,6 +388,7 @@
color: #333333;
font-weight: 600;
margin-bottom: 20rpx;
min-height: 36rpx;
}
.title-icon {
@@ -19,7 +19,7 @@
{{ item.examCnt || 0 }}
<uv-icon
class="click_text_icon"
:class="{click_text_icon_action:show_list_state}"
:class="{ click_text_icon_action: show_list_state }"
name="arrow-right"
color="#0066FF"
size="12"
@@ -47,9 +47,10 @@
<uv-icon name="arrow-right" color="#979797" size="17" :bold="true"></uv-icon>
</view>
<uv-load-more
v-if="status === 'loading'"
v-if="status !== 'nomore'"
@click="getData()"
:status="status"
loadmore-text="轻轻上拉加载"
loadmore-text="点击加载更多"
:height="30"
></uv-load-more>
</view>
@@ -60,7 +61,7 @@
import { computed, ref, reactive } from 'vue';
import common from '@/common/common';
import { queryCrsExamHisByExamId } from '@/api/courseRecord.js';
const status = ref('loadmore'); // loadmore - 加载前,loading - 加载中,nomore - 没有数据
import { useItemList } from '../useItemList.js';
const props = defineProps({
item: {
type: Object,
@@ -68,33 +69,9 @@
}
});
const item = computed(() => props.item);
const data_list = reactive([]);
const total = ref(-1);
const show_list_state = ref(false);
const list_div_height = computed(() => {
if (!show_list_state.value) {
return '0';
} else if (status.value === 'loading') {
return '100rpx';
} else {
return data_list.length * 136 + 'rpx';
}
});
// 点击获取考试详情
const show_list_click = () => {
show_list_state.value = !show_list_state.value;
if (total.value === -1) {
//加载数据
status.value = 'loading';
data_list.length = 0;
queryCrsExamHisByExamId({ examId: item.value.examId }).then((res) => {
data_list.push(...res.body);
total.value = data_list.length;
status.value = 'loadmore';
});
}
};
const fetchFunction = (params) => queryCrsExamHisByExamId({ examId: item.value.examId, ...params });
const { status, data_list, show_list_state, list_div_height, show_list_click, getData } = useItemList(fetchFunction);
// 跳转到详情
const click_list_item = (list_item) => {
const papersName = item.value.examName;
@@ -247,7 +224,7 @@
/* 添加过渡动画,包含延迟效果 */
transition: transform 0.2s ease;
}
.click_text_icon_action{
.click_text_icon_action {
transform: rotate(90deg);
}
}
@@ -47,9 +47,10 @@
<uv-icon name="arrow-right" color="#979797" size="17" :bold="true"></uv-icon>
</view>
<uv-load-more
v-if="status === 'loading'"
v-if="status !== 'nomore'"
@click="getData()"
:status="status"
loadmore-text="轻轻上拉加载"
loadmore-text="点击加载更多"
:height="30"
></uv-load-more>
</view>
@@ -60,7 +61,8 @@
import { computed, ref, reactive } from 'vue';
import common from '@/common/common';
import { queryPracticeHis } from '@/api/courseRecord.js';
const status = ref('loadmore'); // loadmore - 加载前,loading - 加载中,nomore - 没有数据
import { useItemList, formatDuration } from '../useItemList.js';
const props = defineProps({
item: {
type: Object,
@@ -68,60 +70,15 @@
}
});
const item = computed(() => props.item);
const data_list = reactive([]);
const total = ref(-1);
const show_list_state = ref(false);
const list_div_height = computed(() => {
if (!show_list_state.value) {
return '0';
} else if (status.value === 'loading') {
return '100rpx';
} else {
return data_list.length * 136 + 'rpx';
}
});
// 点击获取详情
const show_list_click = () => {
show_list_state.value = !show_list_state.value;
if (total.value === -1) {
//加载数据
status.value = 'loading';
data_list.length = 0;
queryPracticeHis({ crsId: item.value.crsId }).then((res) => {
data_list.push(...res.body);
total.value = data_list.length;
status.value = 'loadmore';
});
}
};
const fetchFunction = (params) => queryPracticeHis({ crsId: item.value.crsId, ...params });
const { status, data_list, show_list_state, list_div_height, show_list_click, getData } = useItemList(fetchFunction);
// 跳转到详情
const click_list_item = (list_item) => {
common.navigateTo(`/pages/courseRecord/coursePracticeRecordDetail?exrId=${list_item.exrId}`);
};
// 计算两个标准时间的时间差值
const formatDuration = (startTm, endTm) => {
if(endTm === null || startTm === null) return "00:00:00";
// 解析时间字符串为时间戳(毫秒)
const startTime = new Date(startTm).getTime();
const endTime = new Date(endTm).getTime();
// 计算时间差(秒),确保为正数
const seconds = Math.abs(Math.floor((endTime - startTime) / 1000));
// 计算时、分、秒
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
const remainingSeconds = seconds % 60;
// 补零格式化函数(统一处理所有单位)
const formatNumber = (num) => num.toString().padStart(2, '0');
// 小时、分钟、秒均保持两位数格式
return `${formatNumber(hours)}:${formatNumber(minutes)}:${formatNumber(remainingSeconds)}`;
};
</script>
<style scoped lang="scss">
@@ -47,9 +47,10 @@
<uv-icon name="arrow-right" color="#979797" size="17" :bold="true"></uv-icon>
</view>
<uv-load-more
v-if="status === 'loading'"
v-if="status !== 'nomore'"
@click="getData()"
:status="status"
loadmore-text="轻轻上拉加载"
loadmore-text="点击加载更多"
:height="30"
></uv-load-more>
</view>
@@ -57,10 +58,10 @@
</template>
<script setup>
import { computed, ref, reactive } from 'vue';
import { computed } from 'vue';
import common from '@/common/common';
import { queryStdyBatchByCrsId } from '@/api/courseRecord.js';
const status = ref('loadmore'); // loadmore - 加载前,loading - 加载中,nomore - 没有数据
import { useItemList, formatDuration, secondsToHours } from '../useItemList.js';
const props = defineProps({
item: {
type: Object,
@@ -68,67 +69,16 @@
}
});
const item = computed(() => props.item);
const data_list = reactive([]);
const total = ref(-1);
const show_list_state = ref(false);
const list_div_height = computed(() => {
if (!show_list_state.value) {
return '0';
} else if (status.value === 'loading') {
return '100rpx';
} else {
return data_list.length * 136 + 'rpx';
}
});
const secondsToHours = (seconds) => {
if (typeof seconds === 'number') {
// 转换为小时并保留一位小数
return (seconds / 3600).toFixed(1);
}
return '0.0';
};
// 点击获取详情
const show_list_click = () => {
show_list_state.value = !show_list_state.value;
if (total.value === -1) {
//加载数据
status.value = 'loading';
data_list.length = 0;
queryStdyBatchByCrsId({ crsId: item.value.crsId }).then((res) => {
data_list.push(...res.body);
total.value = data_list.length;
status.value = 'loadmore';
});
}
};
const fetchFunction = (params) => queryStdyBatchByCrsId({ crsId: item.value.crsId, ...params });
const { status, data_list, show_list_state, list_div_height, show_list_click, getData } = useItemList(fetchFunction);
// 跳转到详情
const click_list_item = (list_item) => {
common.navigateTo(
`/pages/courseRecord/courseStudyRecordDetail?stdyId=${list_item.stdyBatch}&crsName=${item.value.crsName || ''}`
);
};
// 计算两个标准时间的时间差值
const formatDuration = (startTm, endTm) => {
if(endTm === null || startTm === null) return "00:00:00";
// 解析时间字符串为时间戳(毫秒)
const startTime = new Date(startTm).getTime();
const endTime = new Date(endTm).getTime();
// 计算时间差(秒),确保为正数
const seconds = Math.abs(Math.floor((endTime - startTime) / 1000));
// 计算时、分、秒
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
const remainingSeconds = seconds % 60;
// 补零格式化函数(统一处理所有单位)
const formatNumber = (num) => num.toString().padStart(2, '0');
// 小时、分钟、秒均保持两位数格式
return `${formatNumber(hours)}:${formatNumber(minutes)}:${formatNumber(remainingSeconds)}`;
};
</script>
<style scoped lang="scss">
+106
View File
@@ -0,0 +1,106 @@
import {
computed,
reactive,
nextTick,
ref
} from 'vue';
// 计算两个标准时间的时间差值
export const formatDuration = (startTm, endTm) => {
if (endTm === null || startTm === null) return "00:00:00";
// 解析时间字符串为时间戳(毫秒)
const startTime = new Date(startTm).getTime();
const endTime = new Date(endTm).getTime();
// 计算时间差(秒),确保为正数
const seconds = Math.abs(Math.floor((endTime - startTime) / 1000));
// 计算时、分、秒
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
const remainingSeconds = seconds % 60;
// 补零格式化函数(统一处理所有单位)
const formatNumber = (num) => num.toString().padStart(2, '0');
// 小时、分钟、秒均保持两位数格式
return `${formatNumber(hours)}:${formatNumber(minutes)}:${formatNumber(remainingSeconds)}`;
};
// 秒数转换成小时,带小数点的小时
export const secondsToHours = (seconds) => {
if (typeof seconds === 'number') {
// 转换为小时并保留一位小数
return (seconds / 3600).toFixed(1);
}
return '0.0';
};
export function useItemList(fetchFunction, item) {
const status = ref('loadmore'); // loadmore - 加载前,loading - 加载中,nomore - 没有数据
const limit = 5;
const page = ref(0);
const total = ref(-1);
const data_list = reactive([]);
const show_list_state = ref(false);
const list_div_height = computed(() => {
const statusHeight = status.value === 'nomore' ? 0 : 100;
if (!show_list_state.value) {
return '0';
} else if (status.value === 'loading') {
return data_list.length * 136 + statusHeight + 'rpx';
} else {
return data_list.length * 136 + statusHeight + 'rpx';
}
});
// 点击获取详情
const show_list_click = () => {
show_list_state.value = !show_list_state.value;
if (show_list_state.value) {
nextTick(() => {
getData('first');
});
}
};
const getData = (from = '') => {
if (from === 'first') {
if (total.value !== -1) {
return;
}
status.value = 'loading';
total.value = -1;
page.value = 1;
data_list.length = 0;
} else {
if (status.value !== 'loadmore' && status.value !== '') return;
status.value = 'loading';
page.value++;
}
fetchFunction({
page: page.value,
limit: limit
})
.then((res) => {
total.value = res.total;
data_list.push(...res.body);
})
.finally(() => {
if (data_list.length >= total.value) {
status.value = 'nomore';
} else {
status.value = 'loadmore';
}
});
};
return {
status,
data_list,
show_list_state,
list_div_height,
show_list_click,
getData
};
}
@@ -40,11 +40,8 @@
const close = () => PopupRef.value?.close();
const open = (dialogConfiguration) => {
console.log('dialogConfiguration', dialogConfiguration);
// 解构赋值更清晰
const { title: t, html: h, buttonList: bl = [] } = dialogConfiguration || props.dialogConfiguration || {};
console.log('title', title);
title.value = t || '';
html.value = h || '';
buttonList.value = Array.isArray(bl) ? bl : [];
+44 -9
View File
@@ -161,7 +161,7 @@
import { getPageCache, setupKeyboardHeightListener } from '@/common/common';
import { commonUploadVoiceFile } from '@/api/common.js';
import { optionErrorIcon, examinationSheetIcon, practiceExitIcon } from '@/common/imgSvg';
import { commitPaperExam, commitCrsExam } from '@/api/examination.js';
import { commitPaperExam, commitCrsExam, commitPaperCache } from '@/api/examination.js';
const answerIsOver = ref(true);
const feedbackRef = ref(null);
const dialogRef = ref(null);
@@ -199,7 +199,7 @@
get: () => topicList[questionNumber.value],
set: (val) => (topicList[questionNumber.value] = val)
});
const showTouchBtn = computed(() => {
return topic.value?.qnsTyp === 'ES' && !topic.value?.my_answer.anserResult;
});
@@ -266,7 +266,7 @@
questionNumber.value = index;
popupRef.value.close();
};
const subject_click = (type, params) => {
if (type === 'mark') {
topicList[questionNumber.value]['mark'] = !topicList[questionNumber.value]['mark'];
@@ -277,6 +277,16 @@
// 问答题点击重答
topic.value.my_answer = {};
topic.value.es_status = ''; // 取消转圈
} else if (type === 'answer') {
//多选点击按钮答题
if (params.qnsTyp === 'MU') {
hand_in_paper_cache()
}
} else if (type === 'choose') {
//单选判断点击选项答题
if (['JD', 'SN'].includes(params.qnsTyp)) {
hand_in_paper_cache()
}
}
};
@@ -316,7 +326,12 @@
};
}
};
// 添加试题答案缓存
const addTopicAnswerCache = () => {
}
// 初始化时检查
onLoad(() => {
const examination = getPageCache('examination');
@@ -332,6 +347,8 @@
paperData.papersId = examination.papersId;
paperData.limitTm = examination.limitTm;
paperData.papersName = examination.papersName;
// 获取上一次答题的缓存
// const answerCacheList = common.getValue('')
topicList.push(
...examination.qnsInfoVos.map((res) => ({
...res,
@@ -442,10 +459,10 @@
}
dialogRef.value.open();
};
// 执行交卷
const hand_in_paper = (strs = '') => {
console.log('交卷的原因', strs);
const answerDtoList = topicList.map((res) => {
// 整理题目成为要提交的格式
const getAnswerDtoList = () => {
return topicList.map((res) => {
let answerItem = {
examId: paperData.examId,
papersId: paperData.papersId,
@@ -469,6 +486,24 @@
};
}
});
};
// 提交当前所有填写了答案的题的缓存
const hand_in_paper_cache = () => {
const answerDtoList = getAnswerDtoList();
commitPaperCache({
examTyp: paperData.examId ? 'PAPERS' : 'CRS',
papersId: paperData.papersId,
examId: paperData.examId??'',
execId: paperData.execId,
answerDtoStr: JSON.stringify(answerDtoList)
}).then((res) => {
console.log('提交当前所有填写了答案的题的缓存222222', res);
});
};
// 执行交卷
const hand_in_paper = (strs = '') => {
console.log('交卷的原因', strs);
const answerDtoList = getAnswerDtoList();
// 计算当前时间与开始时间的毫秒差值,再转换为整数秒
const examLenTm = Math.floor((new Date().getTime() - examinationStartTime) / 1000);
dialogRef.value.close();
@@ -479,7 +514,7 @@
// 这里是考试中心考试
func = commitPaperExam({
papersId: paperData.papersId,
examId: paperData.examId,
examId: paperData.examId??'',
execId: paperData.execId,
examLenTm: examLenTm,
answerDtoStr: JSON.stringify(answerDtoList)
+3 -3
View File
@@ -67,7 +67,7 @@
时长{{ formatSecondsToText(result.examLenTm) }}
</view>
<view class="fl1"></view>
<view class="examination" @click="goExamRanking" v-if="result.mode === 'examination'">
<view class="examination" @click="goExamRanking" v-if="result.mode === 'examination' && flagQuery === 'Y'">
<view>考试排行榜</view>
<view class="back-icon"></view>
</view>
@@ -76,7 +76,7 @@
</view>
<view class="main-div">
<view class="answer_title">答题详情</view>
<view class="sheet_table_div" v-if="pass_status !== 0 && topicList.length > 0">
<view class="sheet_table_div" v-if="pass_status !== 0 && topicList.length > 0 && flagQueryDetail === 'Y'">
<swiper
:indicator-dots="false"
class="sheet_swiper"
@@ -105,7 +105,7 @@
<image src="@/static/images/examination/unable_img.png" mode="widthFix" class="img"></image>
<view class="tip">您暂无权限查看此试卷详情</view>
</view>
<view v-show="index === sheet_index" :class="getStatusClass(index)" v-for="(item, index) in topicList">
<view v-if="flagQueryDetail === 'Y'" 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>
@@ -47,9 +47,10 @@
<uv-icon name="arrow-right" color="#979797" size="17" :bold="true"></uv-icon>
</view>
<uv-load-more
v-if="status === 'loading'"
v-if="status !== 'nomore'"
@click="getData()"
:status="status"
loadmore-text="轻轻上拉加载"
loadmore-text="点击加载更多"
:height="30"
></uv-load-more>
</view>
@@ -59,48 +60,24 @@
<script setup>
import { computed, ref, reactive } from 'vue';
import common from '@/common/common';
const status = ref('loadmore'); // loadmore - 加载前,loading - 加载中,nomore - 没有数据
import { useItemList } from '../../courseRecord/useItemList.js';
import { queryExamHisByExamId } from '@/api/courseRecord.js';
const props = defineProps({
item: {
type: Object,
default: () => {}
}
});
import { queryExamHisByExamId } from '@/api/courseRecord.js';
const item = computed(() => props.item);
const data_list = reactive([]);
const total = ref(-1);
const show_list_state = ref(false);
const list_div_height = computed(() => {
if (!show_list_state.value) {
return '0';
} else if (status.value === 'loading') {
return '100rpx';
} else {
return data_list.length * 136 + 'rpx';
}
});
// 点击获取考试详情
const show_list_click = () => {
show_list_state.value = !show_list_state.value;
if (total.value === -1) {
//加载数据
status.value = 'loading';
data_list.length = 0;
queryExamHisByExamId({ examId: item.value.examId }).then((res) => {
data_list.push(...res.body);
total.value = data_list.length;
status.value = 'loadmore';
});
}
};
const fetchFunction = (params) => queryExamHisByExamId({ examId: item.value.examId, ...params });
const { status, data_list, show_list_state, list_div_height, show_list_click, getData } = useItemList(fetchFunction);
// 跳转到详情
const click_list_item = (list_item) => {
const papersName = item.value.examName;
const flagQueryDetail = list_item.flagQueryDetail === '' ? list_item.flagQuery : list_item.flagQueryDetail;
common.navigateTo(
`/pages/examination/result?execId=${list_item.execId}&papersName=${papersName}&mode=record&flagQuery=Y&flagQueryDetail=Y`
`/pages/examination/result?execId=${list_item.execId}&papersName=${papersName}&mode=record&flagQuery=${list_item.flagQuery}&flagQueryDetail=${flagQueryDetail}`
);
};
</script>
+1 -1
View File
@@ -119,7 +119,7 @@
get: () => topicList[questionNumber.value],
set: (val) => (topicList[questionNumber.value] = val)
});
const showTouchBtn = computed(() => {
return topic.value?.qnsTyp === 'ES' && !topic.value?.my_answer.anserResult;
});
+6 -5
View File
@@ -89,8 +89,7 @@
import { getPageCache, setupKeyboardHeightListener } from '@/common/common';
import { commonUploadVoiceFile } from '@/api/common.js';
import { practiceExitIcon } from '@/common/imgSvg';
import { practiceCommit, queryCrsPracticeAnswerResult } from '@/api/practice.js';
import { queryMistakesAnswerByMisId, mistakesCorrect } from '@/api/wrongQuestionRecord.js';
import { queryMistakesAnswerByMisId, mistakesCorrect, queryMistakesCorrectByMisId } from '@/api/wrongQuestionRecord.js';
const feedbackRef = ref(null);
const dialogRef = ref(null);
const touchBtnRef = ref(null);
@@ -196,7 +195,8 @@
// 是问答题
if (topic.value.qnsTyp === 'ES') {
try {
const result = await queryWithRetry(res.body.execLogId);
const result = await queryWithRetry(topic.value.misId);
console.log(result, 'result');
traQnsInfoVo = result.body.traQnsInfoVo;
} catch (e) {
common.hideLoading();
@@ -254,9 +254,9 @@
if (maxRetries <= 0) {
return Promise.reject(new Error('超过最大重试次数,查询失败'));
}
return queryCrsPracticeAnswerResult({ execLogId })
return queryMistakesCorrectByMisId({ misId:execLogId })
.then((res) => {
console.log('queryCrsPracticeAnswerResult', maxRetries, res.body);
console.log('queryMistakesCorrectByMisId', maxRetries, res.body);
const isWait = res.body.isWait;
if (isWait === 'Y') {
// 如果是Y,延迟2秒后重试,重试次数减1
@@ -324,6 +324,7 @@
const addProblem = async (index) => {
// index 要加载的题号
if (index < topicList.length) return true; // 说明此题已经加载
console.log('xxx', topicList.length, storageIdList.value.length);
if (topicList.length >= storageIdList.value.length) return false; // 说明已经加载所有题了
const id = storageIdList.value[index]; // 找到id