增加考试中心下拉刷新功能

This commit is contained in:
田岩
2025-09-17 15:48:58 +08:00
parent fe7e4b6a1e
commit 376e54f4dd
11 changed files with 218 additions and 257 deletions
+1 -1
View File
@@ -24,7 +24,7 @@ VITE_APP_BASE_API_Url = 'https://aitstest.jlbank.com.cn:7002'
# dev
VITE_APP_BASE_H5_API_Url = 'http://25.18.122.65:7001'
# VITE_APP_BASE_H5_API_Url = 'http://25.18.122.65:7002'
# sit
# VITE_APP_BASE_H5_API_Url = 'http://25.18.122.92:9786'
+10
View File
@@ -31,6 +31,16 @@ export const queryPaperExamScore = (data) => {
data
});
};
// 根据试卷id查询详情
export const queryTraExamPapersByPapersId = (data) => {
return request({
url: base_url + '/traExamPapers/queryTraExamPapersByPapersId',
method: 'post',
toastErrors: true,
data
});
};
// ↑↑↑↑↑↑↑↑↑考试中心考试↑↑↑↑↑↑↑
@@ -14,7 +14,7 @@
<view class="bottom">历史最高分</view>
</view>
<view class="prompt_div_line"></view>
<view class="prompt_div_right" @click="show_list_click">
<view class="prompt_div_right" @click="show_list_click(item.examCnt)">
<view class="click_text">
{{ item.examCnt || 0 }}
<uv-icon
@@ -14,7 +14,7 @@
<view class="bottom">答题正确率</view>
</view>
<view class="prompt_div_line"></view>
<view class="prompt_div_right" @click="show_list_click">
<view class="prompt_div_right" @click="show_list_click(item.exrCnt)">
<view class="click_text">
{{ item.exrCnt || '0' }}
<uv-icon
@@ -14,7 +14,7 @@
<view class="bottom">学习时长</view>
</view>
<view class="prompt_div_line"></view>
<view class="prompt_div_right" @click="show_list_click">
<view class="prompt_div_right" @click="show_list_click(item.stdyCnt)">
<view class="click_text">
{{ item.stdyCnt || 0 }}
<uv-icon
+2 -1
View File
@@ -55,7 +55,8 @@ export function useItemList(fetchFunction, item) {
}
});
// 点击获取详情
const show_list_click = () => {
const show_list_click = (num = -1) => {
if (num === 0) return;
show_list_state.value = !show_list_state.value;
if (show_list_state.value) {
nextTick(() => {
+1 -2
View File
@@ -150,7 +150,6 @@
import { queryAllTraTaskCrsInfo, queryTraTaskInfoByTaskId } from '@/api/learningTasks.js';
import { passTheExamIcon, completeTheExercisesIcon, lockIcon } from '@/common/imgSvg';
import { insertTraPersonalCollectionTask, deleteTraPersonalCollectionById } from '@/api/favorites.js';
import useZpaging from '@/composables/useZpaging.js';
import common from '@/common/common';
import { getPageCache } from '@/common/common';
@@ -528,7 +527,7 @@
background-position: top;
background-color: #fff;
}
.detail_div {
height: 250rpx;
z-index: 2;
@@ -32,6 +32,7 @@
setPageCache('testing_hall_details', item)
common.navigateTo('/pages/testingHall/details');
}
</script>
<style scoped lang="scss">
+15 -73
View File
@@ -36,13 +36,13 @@
import useZpaging from '@/composables/useZpaging.js';
const examStat = computed(() => ['', 'Y', 'N'][props.currentIndex]);
const examStat = computed(() => ['', 'Y', 'N'][props.tabIndex]);
const fetchFunction = (params) => queryTraExamPapersPage({ examStat: examStat.value, ...params });
const { pagingRef, queryList, data_list, reload, search, total, clear } = useZpaging({
fetchFunction,
searchKey: 'papersName'
});
const props = defineProps({
tabIndex: {
type: Number,
@@ -53,76 +53,18 @@
default: 0
}
});
// const getData = (from = '', _searchText = '') => {
// 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++;
// }
// setTimeout(() => {
// let params = {
// papersName: _searchText || searchText.value,
// page: page.value,
// limit: limit
// };
// if (props.currentIndex === 1) {
// params.examStat = 'Y';
// } else if (props.currentIndex === 2) {
// params.examStat = 'N';
// }
// queryTraExamPapersPage(params)
// .then((res) => {
// total.value = res.total;
// data_list.push(...res.body);
// console.log('total.value', total.value);
// })
// .catch((res) => {
// console.log('resres', res);
// })
// .finally(() => {
// if (data_list.length >= total.value) {
// status.value = 'nomore';
// } else {
// status.value = 'loadmore';
// }
// });
// }, 200);
// };
// const scrolltolower = () => {
// getData();
// };
// const searchText = ref('');
// const search = (value, state) => {
// console.log('value', value, state);
// total.value = -1;
// searchText.value = value;
// if (state) {
// getData('first', value);
// } else {
// total.value = -1;
// page.value = 1;
// data_list.length = 0;
// }
// };
// const clear = (state) => {
// total.value = -1;
// page.value = 1;
// data_list.length = 0;
// };
const updateData = (item) => {
// const index = data_list.findIndex((res) => res.taskId === item.taskId);
// console.log('updateData', index, item);
// if (index !== -1) {
// data_list[index] = item;
// }
if(props.tabIndex !== 0 && item.examStatText === 'Y') {
reload()
} else{
const index = data_list.value.findIndex((res) => res.taskId === item.taskId);
if (index !== -1) {
Object.assign(data_list.value[index], {
...item
});
}
}
};
onMounted(() => {
watch(
@@ -164,8 +106,8 @@
// }
.scroll-Y {
background-color: #f1f5fa;
border-radius: 16rpx;
padding: 1rpx 12rpx 0 22rpx;
padding: 1rpx 22rpx 0 22rpx;
}
</style>
+173 -131
View File
@@ -1,145 +1,142 @@
<template>
<view class="main_div max_page">
<view class="my-nav-bar"></view>
<view class="body-title">
<view class="back_div" @click="common.navigateBack()">
<view class="back-icon"></view>
</view>
<view>考试详情</view>
</view>
<view class="detail_div" :class="detailData.examStatText == 'Y' ? 'completed' : 'incomplete'">
<view class="subscript" v-if="detailData.examStatText === 'N'">未完成</view>
<view class="subscript" v-if="detailData.examStatText === 'Y'">已完成</view>
<view class="title_div">
<view class="title ellipsis-text">{{ detailData.papersName }}</view>
</view>
<view class="time">
<text class="color_3">起止时间</text>
<text class="color_class">{{ detailData.examStartTm }}{{ detailData.examEndTm }}</text>
</view>
<view class="num_div">
<text class="color_3">完成人数</text>
<text class="color_2">{{ detailData.execPersionNumer }}/{{ detailData.planPersionNumber }}</text>
</view>
</view>
<view class="paper_div">
<view class="paper">
<!-- 试卷信息 -->
<view class="paper_title_div">
<image src="@/static/images/testingHall/testing.png" class="img"></image>
<view class="title">试卷信息</view>
<z-paging ref="pagingRef" @query="query" :loading-more-enabled="false" :refresher-only="true" :aoto="false">
<template #top>
<view class="body-title">
<view class="back_div" @click="common.navigateBack()">
<view class="back-icon"></view>
</view>
<view class="title-note">
考试时长
<text class="bold">{{ detailData.limitTm / 60 }}</text>
分钟
<view>考试详情</view>
</view>
</template>
<view class="main_div max_page">
<view class="detail_div" :class="detailData.examStatText == 'Y' ? 'completed' : 'incomplete'">
<view class="subscript" v-if="detailData.examStatText === 'N'">未完成</view>
<view class="subscript" v-if="detailData.examStatText === 'Y'">已完成</view>
<view class="title_div">
<view class="title ellipsis-text">{{ detailData.papersName }}</view>
</view>
<view class="title-table">
<view class="title-table-item">
<view class="top">
<text class="text_2">{{ detailData.totalGrade }}</text>
<text class="text_1"></text>
</view>
<view class="bottom text_1">试卷总分</view>
<view class="time">
<text class="color_3">起止时间</text>
<text class="color_class">{{ detailData.examStartTm }}{{ detailData.examEndTm }}</text>
</view>
<view class="num_div">
<text class="color_3">完成人数</text>
<text class="color_2">{{ detailData.execPersionNumer }}/{{ detailData.planPersionNumber }}</text>
</view>
</view>
<view class="paper_div">
<view class="paper">
<!-- 试卷信息 -->
<view class="paper_title_div">
<image src="@/static/images/testingHall/testing.png" class="img"></image>
<view class="title">试卷信息</view>
</view>
<view class="title-table-item">
<view class="top">
<text class="text_2">{{ detailData.passGrade }}</text>
<text class="text_1"></text>
<view class="title-note">
考试时长
<text class="bold">{{ detailData.limitTm / 60 }}</text>
分钟
</view>
<view class="title-table">
<view class="title-table-item">
<view class="top">
<text class="text_2">{{ detailData.totalGrade }}</text>
<text class="text_1"></text>
</view>
<view class="bottom text_1">试卷总分</view>
</view>
<view class="title-table-item">
<view class="top">
<text class="text_2">{{ detailData.passGrade }}</text>
<text class="text_1"></text>
</view>
<view class="bottom text_1">通过分数</view>
</view>
<view class="title-table-item">
<view class="top text_2">
{{ detailData.limitTypText }}
<view class="bottom text_1">通过分数</view>
</view>
<view class="bottom text_1">通过次数</view>
</view>
<view class="title-table-item">
<view class="top text_2">
{{ detailData.papersTypText || '随机' }}
<view class="title-table-item">
<view class="top text_2">
{{ detailData.limitTypText }}
</view>
<view class="bottom text_1">通过次数</view>
</view>
<view class="bottom text_1">试卷类型</view>
</view>
</view>
<view class="table">
<view class="table_th">
<view class="table_td">题型</view>
<view class="fl1"></view>
<view class="table_td">数量</view>
<view class="table_td">分值</view>
</view>
<view
class="table_tr"
v-for="(t, t_index) in detailData.papersPlateVos"
:class="{ table_tr_dark: t_index % 2 }"
>
<view class="table_td">
{{ t.plateName }}
</view>
<view class="fl1"></view>
<view class="table_td">
{{ t.qnsNumber }}
</view>
<view class="table_td">
{{ t.tgtGrade }}
<view class="title-table-item">
<view class="top text_2">
{{ detailData.papersTypText || '随机' }}
</view>
<view class="bottom text_1">试卷类型</view>
</view>
</view>
<view class="table_tr">
<view class="table_td">总计</view>
<view class="fl1"></view>
<view class="table_td">
{{ allNumber }}
<view class="table">
<view class="table_th">
<view class="table_td">题型</view>
<view class="fl1"></view>
<view class="table_td">数量</view>
<view class="table_td">分值</view>
</view>
<view class="table_td">
{{ allGrade }}
<view
class="table_tr"
v-for="(t, t_index) in detailData.papersPlateVos"
:class="{ table_tr_dark: t_index % 2 }"
>
<view class="table_td">
{{ t.plateName }}
</view>
<view class="fl1"></view>
<view class="table_td">
{{ t.qnsNumber }}
</view>
<view class="table_td">
{{ t.tgtGrade }}
</view>
</view>
<view class="table_tr">
<view class="table_td">总计</view>
<view class="fl1"></view>
<view class="table_td">
{{ allNumber }}
</view>
<view class="table_td">
{{ allGrade }}
</view>
</view>
</view>
</view>
</view>
</view>
<view class="fixed_button_div" @click="goto_examination()">
<uv-button
type="primary"
class="send_evaluate"
:custom-style="customStyle"
:throttleTime="300"
:hairline="false"
:disabled="isTimeInvalid"
>
开始考试
</uv-button>
</view>
</view>
<template #bottom>
<view class="fixed_button_div" @click="goto_examination()">
<uv-button
type="primary"
class="send_evaluate"
:custom-style="customStyle"
:throttleTime="300"
:hairline="false"
:disabled="isTimeInvalid"
>
开始考试
</uv-button>
</view>
</template>
</z-paging>
</template>
<script setup>
import {
onLoad,
onUnload
} from '@dcloudio/uni-app'
import { reactive, computed } from 'vue';
import { startTraExamPapersInfo } from '@/api/examination.js';
import { onLoad, onUnload } from '@dcloudio/uni-app';
import { reactive, computed, ref } from 'vue';
import { startTraExamPapersInfo, queryTraExamPapersByPapersId } from '@/api/examination.js';
import common from '@/common/common';
import { setPageCache, getPageCache } from '@/common/common';
import useZpaging from '@/composables/useZpaging.js';
const pagingRef = ref(null);
const detailData = reactive({
papersId: '',
papersName: '',
examStartTm: '',
examEndTm: '',
execPersionNumer: '',
planPersionNumber: '',
judgeNumber: 0,
singleNumber: 0,
multiNumber: 0,
essayNumber: 0,
judgeGrade: 0,
singleGrade: 0,
multiGrade: 0,
essayGrade: 0
planPersionNumber: ''
});
const customStyle = {
backgroundColor: '#0066FF',
@@ -171,7 +168,38 @@
// 未开始或已结束都返回true(不符合时间要求)
return current < start || current > end;
});
const query = () => {
setTimeout(() => {
queryTraExamPapersByPapersId({ papersId: detailData.papersId }).then((res) => {
console.log('水水水水', res.body);
const compareKeys = [
'examId',
'papersName',
'examStartTm',
'examEndTm',
'execPersionNumer',
'planPersionNumber',
'totalGrade',
'execPersionNumer',
'examStatText'
];
const detailsData = res.body;
// // 检查是否需要更新
const needUpdate = compareKeys.some((key) => {
return detailData[key] !== detailsData[key];
});
console.log('检查是否需要更新', needUpdate);
if (needUpdate) {
Object.assign(detailData, {
...detailsData
});
uni.$emit('update_testing_hall_item', detailsData);
}
pagingRef.value.endRefresh();
});
}, 200);
};
const goto_examination = async () => {
if (detailData.limitTyp === 'SG' && detailData.examStatText === 'Y') return common.msg('考试已完成');
const startTime = new Date(detailData.examStartTm);
@@ -204,24 +232,23 @@
Object.assign(detailData, {
...testing_hall_details
});
uni.$on('exam_completed', (res) => { // 考试完成,考试中心这里任务要完成
console.log('refresh_testing_hall_data');
// contentRefs.value[0]?.updateData(res);
uni.$on('get_result_completed', (res) => {
// 考试完成,考试中心这里任务要完成
setTimeout(() => {
pagingRef.value.reload();
}, 100);
});
});
onUnload(() => {
uni.$off('exam_completed');
uni.$off('get_result_completed');
});
</script>
<style scoped lang="scss">
.fixed_button_div {
position: fixed;
bottom: 30rpx;
width: calc(100vw - 60rpx);
margin: 0 auto 30rpx auto;
}
.title-table {
@@ -369,21 +396,38 @@
background-color: #337fff;
}
.body-title {
background-color: #337fff;
// background-color: #337fff;
// width: 100%;
// position: relative;
// text-align: center;
// height: 120rpx;
// line-height: 100rpx;
// font-family: PingFangSC;
// font-weight: 500;
// font-size: 38rpx;
// color: #ffffff;
// font-style: normal;
// padding-top: var(--status-bar-height);
}
.body-title {
width: 100%;
position: relative;
text-align: center;
height: 120rpx;
line-height: 100rpx;
height: 180rpx;
padding-top: var(--status-bar-height);
margin-bottom: -10rpx;
line-height: calc(180rpx - var(--status-bar-height) - 10rpx);
font-family: PingFangSC;
font-weight: 500;
font-size: 38rpx;
font-size: 32rpx;
color: #ffffff;
font-style: normal;
background-color: #337fff;
}
.detail_div {
margin-top: -20rpx;
height: 250rpx;
z-index: 2;
width: 100%;
padding: 48rpx 40rpx 20rpx 40rpx;
@@ -481,11 +525,9 @@
.back_div {
position: absolute;
left: 26rpx;
height: 100%;
top: -10rpx;
bottom: 20rpx;
display: flex;
align-items: center;
.back-icon {
position: relative;
width: 50rpx;
+12 -46
View File
@@ -28,13 +28,13 @@
</template>
<swiper class="swiper" :current="tabAct" :indicator-dots="false" @change="swiperChange">
<swiper-item>
<Content :ref="(el) => (listItemRefs[0] = el)" :tabIndex="0" :currentIndex="tabAct" @gotoDetails="gotoDetails"></Content>
<Content :ref="(el) => (listItemRefs[0] = el)" :tabIndex="0" :currentIndex="tabAct"></Content>
</swiper-item>
<swiper-item>
<Content :ref="(el) => (listItemRefs[1] = el)" :tabIndex="1" :currentIndex="tabAct" @gotoDetails="gotoDetails"></Content>
<Content :ref="(el) => (listItemRefs[1] = el)" :tabIndex="1" :currentIndex="tabAct"></Content>
</swiper-item>
<swiper-item>
<Content :ref="(el) => (listItemRefs[2] = el)" :tabIndex="2" :currentIndex="tabAct" @gotoDetails="gotoDetails"></Content>
<Content :ref="(el) => (listItemRefs[2] = el)" :tabIndex="2" :currentIndex="tabAct"></Content>
</swiper-item>
</swiper>
</z-paging-swiper>
@@ -42,19 +42,13 @@
<script setup>
// 考试中心
import Content from './components/content.vue';
import { ref, reactive, watch, onMounted } from 'vue';
import { onLoad, onUnload } from '@dcloudio/uni-app';
import { setPageCache } from '@/common/common';
import common from '@/common/common';
import { LineBg } from '@/enum.js';
import common from '@/common/common';
import useIndexList from '@/composables/useIndexList.js';
const { tabAct, listItemRefs, tabChange, swiperChange, search } = useIndexList();
const tabList = ref([
{
@@ -68,55 +62,27 @@
}
]);
const triggered = ref(false);
// const search = (value) => {
// contentRefs.value[0]?.search(value, tabAct.value === 0);
// contentRefs.value[1]?.search(value, tabAct.value === 1);
// contentRefs.value[2]?.search(value, tabAct.value === 2);
// };
const gotoDetails = (item) => {
setPageCache('testing_hall_details', item);
common.navigateTo('/pages/testingHall/details');
};
// onMounted(() => {
// triggered.value = true;
// watch(
// tabAct,
// (newValue, oldValue) => {
// typeof contentRefs.value[newValue]?.getData === 'function' && contentRefs.value[newValue]?.getData('first');
// },
// {
// immediate: true
// }
// ); // 这里的immediate会在onMounted之后执行
// });
onLoad(() => {
uni.$on('refresh_testing_hall_data', (res) => {
// console.log('exam_completed');
// contentRefs.value[0]?.updateData(res);
// contentRefs.value[1]?.updateData(res);
// contentRefs.value[2]?.updateData(res);
uni.$on('update_testing_hall_item', (res) => {
listItemRefs.value[0]?.updateData(res);
listItemRefs.value[1]?.updateData(res);
listItemRefs.value[2]?.updateData(res);
});
});
onUnload(() => {
uni.$off('refresh_testing_hall_data');
uni.$off('update_testing_hall_item');
});
</script>
<style scoped lang="scss">
.swiper {
height: calc(100vh - var(--status-bar-height) - 70rpx - 78rpx - 40rpx - 88rpx);
height: 100%;
width: 100%;
background-color: #f1f5fa;
}
.body-tab {
height: 88rpx;
// background-color: red;
width: 100%;
}
@@ -147,7 +113,7 @@
color: #000;
position: relative;
text-align: center;
.delete_div {
position: absolute;
right: 20rpx;