You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

320 lines
9.1 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<el-container style="min-height: 100vh">
<el-aside :width="sideWidth+'px'" style="background-color: rgb(238, 241, 246); box-shadow: 2px 0 6px rgb(0 21 41 / 35%)">
<Aside :isCollapse="isCollapse" :logoTextShow="logoTextShow"/>
</el-aside>
<el-container>
<el-header style="border-bottom:1px solid #ccc;">
<Header :collapseBtnClass="collapseBtnClass" :collapse="collapse"/>
</el-header>
<el-main>
<div id="app">
<div class="filter-container">
<div class="filter-group">
<label>试卷类型</label>
<button
v-for="(type, index) in paperTypes"
:key="index"
:class="{ active: selectedType === type }"
@click="handleTypeChange(type)"
>
{{ type }}
</button>
</div>
<div class="filter-group">
<label>试卷学科:</label>
<button
v-for="(subject, index) in subjects"
:key="index"
:class="{ active: selectedSubject === subject }"
@click="handleSubjectChange(subject)"
>
{{ subject }}
</button>
</div>
</div>
<div v-if="loading" class="loading">加载中...</div>
<div v-else-if="filteredPapers.length === 0" class="empty">暂无试卷</div>
<div v-else class="card-container">
<div
v-for="(paper, index) in filteredPapers"
:key="index"
class="card"
>
<h3>{{ paper.name }}</h3>
<p>学科{{ paper.subject }}</p>
<p>题目数{{ paper.questionCount }}</p>
<p>试卷总分{{ paper.totalScore }}</p>
<p>考试时长{{ paper.time + " 分钟"}}</p>
<p>开始时间{{ paper.startTime || "未设置" }}</p>
<p>结束时间{{ paper.endTime || "未设置" }}</p>
<button
v-if="paper.hasTaken"
class="start-button taken"
disabled
>
已考过
</button>
<button
v-else
class="start-button"
@click="startExam(paper.id, paper.name, paper.subject, paper.time)"
>
开始答题
</button>
</div>
</div>
</div>
</el-main>
</el-container>
</el-container>
</template>
<script>
import axios from "axios";
import { mapActions } from "vuex";
import Aside from "@/components/Aside.vue";
import Header from "@/components/Header.vue";
export default {
name: 'Exam',
components: {Aside, Header},
data() {
return {
collapse: false,
paperTypes: ["固定试卷", "时段试卷", "班级试卷"], // 试卷类型
subjects: ["语文", "数学"], // 学科
selectedType: "班级试卷", // 默认选中的试卷类型
selectedSubject: "语文", // 默认选中的学科
papers: [], // 试卷数据
loading: true, // 加载状态
tableData: [],
collapseBtnClass: 'el-icon-s-fold',
isCollapse: false,
sideWidth: 200,
logoTextShow: true,
hasTaken:false
};
},
computed: {
filteredPapers() {
// 根据筛选条件动态过滤试卷
return this.papers.filter(
(paper) =>
paper.subject === this.selectedSubject
);
},
},
created() {
this.fetchPapers(); // 页面加载时获取试卷数据
},
watch: {
// 监听试卷类型或学科的变化,调用 fetchPapers 重新加载数据
selectedType() {
this.fetchPapers(); // 当选中的试卷类型改变时,重新加载试卷数据
},
selectedSubject() {
this.fetchPapers(); // 当选中的学科改变时,重新加载试卷数据
},
},
methods: {
startExam(id,name,subject,time) {
this.$router.push({ name: "ExamPaper", query: { id:id ,name: name, subject: subject ,time:time} });
},
handleTypeChange(type) {
this.selectedType = type; // 修改选中的试卷类型
},
handleSubjectChange(subject) {
this.selectedSubject = subject; // 修改选中的学科
},
async checkExamStatus(testId) {
const token = this.$store.state.token;
console.log('token',token);
if (!token) {
alert("用户未登录,请重新登录!");
this.$router.push('/login');
return false;
}
try {
const response = await axios.get(`http://localhost:8080/student/examPaper/whetherTest`, {
params: { testId },
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
});
if (response.status === 200) {
return response.data; // 假设返回的数据中包含 hasTaken 字段
} else {
console.warn("检查考试状态失败:" + response.data.msg);
return false; // 默认未考
}
} catch (error) {
console.error("检查考试状态接口失败:", error);
return false;
}
},
async fetchPapers(page = 1, size = 10) {
const token = this.$store.state.token; // 获取 token
console.log("token:",token);
if (!token) {
alert("用户未登录,请重新登录!");
this.$router.push('/login'); // 引导用户重新登录
return;
}
try {
this.loading = true;
// 确保 page 和 size 参数是有效的
const pageNumber = page || 1; // 使用默认值 1
const pageSize = size || 10; // 使用默认值 10
const response = await axios.get("http://localhost:8080/student/examPaper/examPaperByTypeAndSubject", {
params: {
pagenum: pageNumber,
pagesize: pageSize, // 确保传递 pagesize
type: this.selectedType, // 类型
subject: this.selectedSubject, // 学科
},
headers: {
Authorization: `Bearer ${token}`, // 使用 Vuex 中的 token
'Content-Type': 'application/json',
},
});
if (response.data.code === 200) {
const { records } = response.data.data;
const updatedRecords = await Promise.all(
records.map(async (record) => {
const hasTaken = await this.checkExamStatus(record.id);
return {
id: record.id,
name: record.name,
subject: record.subject,
questionCount: record.totalquestion,
totalScore: record.totalscore,
time: record.time,
startTime: record.start_time || "未设置",
endTime: record.end_time || "未设置",
hasTaken: hasTaken,
};
})
);
this.papers = updatedRecords;
console.log("更新后的试卷数据:", updatedRecords);
} else {
alert("数据加载失败:" + response.data.msg);
this.$router.push('/login'); // 引导用户重新登录
}
} catch (error) {
console.error("获取试卷数据失败:", error);
alert("试卷数据加载失败,请稍后重试!");
} finally {
this.loading = false;
}
}
},
};
</script>
<style scoped>
.start-button.taken {
background-color: #ccc;
cursor: not-allowed;
}
.start-button.taken:hover {
background-color: #ccc; /* 已考过状态无变化 */
}
/* 顶部筛选部分 */
.filter-container {
margin: 20px;
display: flex;
flex-direction: column; /* 设置为垂直排列 */
gap: 15px; /* 使两个筛选组之间有一定的间距 */
}
.filter-group {
display: flex;
align-items: center;
}
.filter-group label {
margin-right: 10px;
font-weight: bold;
}
button {
margin: 5px 10px 5px 0; /* 设置按钮的间距 */
padding: 5px 10px;
border: none;
background-color: #f0f0f0;
cursor: pointer;
}
button.active {
background-color: #007bff;
color: white;
}
/* 卡片部分 */
.card-container {
display: flex;
flex-wrap: wrap;
gap: 20px;
padding: 20px;
justify-content: space-between; /* Ensures spacing between cards */
}
.card {
width: calc(33.333% - 20px); /* Each card takes up 1/3 of the container width, minus gap */
border: 1px solid #ccc;
border-radius: 5px;
padding: 15px;
background-color: #fff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
box-sizing: border-box; /* Ensures padding and border are included in the width */
}
.card h3 {
margin: 0 0 10px;
font-size: 16px;
}
.card p {
margin: 5px 0;
font-size: 14px;
color: #333;
}
.start-button {
margin-top: 10px;
width: 100%;
padding: 5px;
background-color: #007bff;
color: white;
border: none;
border-radius: 3px;
cursor: pointer;
}
.start-button:hover {
background-color: #0056b3;
}
/* 加载和空状态 */
.loading,
.empty {
text-align: center;
padding: 20px;
font-size: 16px;
color: #666;
}
</style>