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.

508 lines
18 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; width: 100%">
<el-aside :width="sideWidth + 'px'" style="background-color: #f4f7fc; box-shadow: 2px 0 6px rgba(0, 21, 41, 0.15)">
<Aside :isCollapse="isCollapse" :logoTextShow="logoTextShow" />
</el-aside>
<el-container style="width: calc(100% - 200px);">
<el-header style="border-bottom: 1px solid #e1e4ea; padding: 10px 20px; background: #fff;">
<Header :collapseBtnClass="collapseBtnClass" :collapse="collapse" />
</el-header>
<el-main style="padding: 20px;">
<el-input
v-model="searchQuery"
placeholder="请输入试卷名称进行搜索"
suffix-icon="el-icon-search"
style="width: 300px; margin-right: 10px;"
/>
<el-button @click="openNewExamDialog" type="primary" size="small">新建试卷</el-button>
<el-table :data="filteredExams" style="width: 100%">
<el-table-column prop="id" label="ID" width="100"></el-table-column>
<el-table-column prop="name" label="名称"></el-table-column>
<el-table-column prop="subject" label="学科"></el-table-column>
<el-table-column prop="grade" label="年级"></el-table-column>
<el-table-column prop="type" label="类型"></el-table-column>
<el-table-column label="操作" width="200">
<template slot-scope="scope">
<el-button @click="openExamDialog(scope.row)" type="primary" size="small">查看试卷</el-button>
<el-button @click="openDistributionDialog(scope.row)" type="primary" size="small">发布情况</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
:current-page="currentPage"
:page-size="pageSize"
:total="totalExams"
@current-change="handlePageChange"
layout="total, prev, pager, next, jumper"
/>
<!-- 查看试卷弹窗 -->
<el-dialog :visible.sync="isExamDialogVisible" title="试卷内容" width="80%" :close-on-click-modal="false">
<el-button @click="openAddQuestionDialog" type="primary" size="small" style="margin-bottom: 20px;">新增题目</el-button>
<div v-if="examQuestions.length > 0" class="exam-table-container">
<el-table :data="examQuestions" style="width: 100%">
<el-table-column label="ID" prop="id" width="60"></el-table-column>
<el-table-column label="题目" prop="content" width="300"></el-table-column>
<!-- 如果题目有选项chance则显示选项列 -->
<el-table-column label="选项" width="400">
<template v-slot="scope">
<div v-if="scope.row.chance && scope.row.chance.length > 0">
<el-row v-for="(option, index) in scope.row.chance" :key="index" type="flex" justify="start" align="middle" class="option-row">
<el-col :span="24">
<el-tag :type="'success'" class="option-tag">
{{ option.label }}: {{ option.text }}
</el-tag>
</el-col>
</el-row>
</div>
</template>
</el-table-column>
<!-- 删除题目列 -->
<el-table-column label="操作" width="180">
<template v-slot="scope">
<el-button @click="deleteQuestion(scope.row.id,)" type="danger" size="small">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="isExamDialogVisible = false" type="primary">关闭</el-button>
</span>
</el-dialog>
<el-dialog :visible.sync="isAddQuestionDialogVisible" title="选择题目" width="60%">
<el-table :data="questionBank" style="width: 100%">
<el-table-column label="题目" prop="content" width="300"></el-table-column>
<el-table-column label="操作" width="180">
<template v-slot="scope">
<el-button @click="addQuestionToExam(scope.row.id)" type="primary" size="small">添加到试卷</el-button>
</template>
</el-table-column>
</el-table>
<span slot="footer" class="dialog-footer">
<el-button @click="isAddQuestionDialogVisible = false">关闭</el-button>
</span>
</el-dialog>
<!-- 分发弹窗 -->
<el-dialog :visible.sync="isDistributionDialogVisible" title="分发试卷">
<el-table :data="classList" style="width: 100%">
<el-table-column prop="grade" label="年级"></el-table-column>
<el-table-column prop="class1" label="班级"></el-table-column>
<el-table-column label="状态" width="180">
<template slot-scope="scope">
<el-tag :type="scope.row.release === 1 ? 'success' : 'danger'" style="border-radius: 5px; font-size: 14px;">
{{ scope.row.release === 1 ? '已发布' : '未发布' }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="180">
<template slot-scope="scope">
<el-button @click="distributeExam(selectedExam.id, scope.row)" type="success" size="small">发布</el-button>
</template>
</el-table-column>
</el-table>
<span slot="footer" class="dialog-footer">
<el-button @click="isDistributionDialogVisible = false">取消</el-button>
</span>
</el-dialog>
<!-- 新建试卷弹窗 -->
<el-dialog :visible.sync="isNewExamDialogVisible" title="新建试卷" width="60%">
<el-form :model="newExamForm" ref="newExamForm" label-width="80px">
<el-form-item label="名称">
<el-input v-model="newExamForm.name" placeholder="请输入试卷名称" style="width: 207.22px"></el-input>
</el-form-item>
<el-form-item label="学科">
<el-select v-model="newExamForm.subject" placeholder="请选择学科">
<el-option label="语文" value="语文"></el-option>
<el-option label="数学" value="数学"></el-option>
<el-option label="英语" value="英语"></el-option>
</el-select>
</el-form-item>
<el-form-item label="年级">
<el-input v-model="newExamForm.grade" placeholder="请输入年级" style="width: 207.22px"></el-input>
</el-form-item>
<el-form-item label="类型">
<el-select v-model="newExamForm.type" placeholder="请选择类型">
<el-option label="班级试卷" value="班级试卷"></el-option>
<el-option label="固定试卷" value="固定试卷"></el-option>
</el-select>
</el-form-item>
<el-form-item label="时间">
<el-input v-model="newExamForm.time" placeholder="请输入考试时间(分钟)" style="width: 207.22px"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="isNewExamDialogVisible = false">取消</el-button>
<el-button type="primary" @click="createExam">确定</el-button>
</span>
</el-dialog>
</el-main>
</el-container>
</el-container>
</template>
<script>
import Header from "@/components/Teacher/Header.vue";
import Aside from "@/components/Teacher/Aside.vue";
import axios from "axios"; // 引入 axios 用于 API 请求
export default {
name: "TeacherExam",
components: { Aside, Header },
data() {
return {
collapseBtnClass: "el-icon-s-fold",
isCollapse: false,
sideWidth: 200,
logoTextShow: true,
exams: [], // 试卷列表
classList: [], // 班级列表
examQuestions: [], //试卷题目
selectedExam: null, // 当前选择的试卷
isDistributionDialogVisible: false, // 分发弹窗显示状态
isExamDialogVisible: false, //试卷题目显示状态
searchQuery: "", // 搜索框的内容
currentPage: 1, // 当前页码
pageSize: 10, // 每页显示的试卷数量
totalExams: 0, // 总试卷数
isAddQuestionDialogVisible: false,//新增题目弹窗
questionBank: [],//题库
isNewExamDialogVisible: false,//新建试卷弹窗
newExamForm: {
name: "",
subject: "",
grade: "",
type: "",
time: ""
},//新建试卷表单
};
},
computed: {
// 计算属性:根据搜索内容过滤试卷列表
filteredExams() {
if (this.searchQuery) {
return this.exams.filter((exam) =>
exam.name.toLowerCase().includes(this.searchQuery.toLowerCase()) // 搜索名称
);
}
return this.exams; // 如果没有输入搜索内容,返回所有试卷
},
},
methods: {
collapse() {
this.isCollapse = !this.isCollapse;
this.sideWidth = this.isCollapse ? 64 : 200;
this.collapseBtnClass = this.isCollapse ? "el-icon-s-unfold" : "el-icon-s-fold";
this.logoTextShow = !this.isCollapse;
},
// 打开新增题目对话框
openAddQuestionDialog() {
this.fetchQuestionBank(); // 获取题库中的题目
this.isAddQuestionDialogVisible = true;
},
// 获取题库中的题目
async fetchQuestionBank() {
try {
const token = this.$store.state.tokens[this.userId];
if (!token) {
alert("用户未登录,请重新登录!");
this.$router.push("/login");
return;
}
const response = await axios.get("http://localhost:8080/examcreate/selectListNotPage", {
headers: { Authorization: `Bearer ${token}` },
});
if (response.data.code === 200) {
this.questionBank = response.data.data; // 存储题库
} else {
this.$message.error("获取题库失败");
}
} catch (error) {
console.error("获取题库失败:", error);
this.$message.error("获取题库失败");
}
},
// 删除题目
async deleteQuestion(questionId) {
try {
const token = this.$store.state.tokens[this.userId];
if (!token) {
alert("用户未登录,请重新登录!");
this.$router.push("/login");
return;
}
const response = await axios.delete(`http://localhost:8080/examcreate/deleteQuestionByExamPaper`, {
params:{
id:questionId,
pid:this.selectedExam.id
},
headers: { Authorization: `Bearer ${token}` },
});
if (response.data.code === 200 && response.data.data > 0) {
this.$message.success("题目删除成功");
// 删除后刷新试卷题目
this.fetchExamQuestions(this.selectedExam.id);
} else {
this.$message.error("删除失败");
}
} catch (error) {
console.error("删除题目失败:", error);
this.$message.error("删除题目失败");
}
},
//打开试卷题目
openExamDialog(exam){
this.selectedExam = exam;
this.fetchExamQuestions(exam.id);
this.isExamDialogVisible = true;
},
// 获取试卷题目
async fetchExamQuestions(examId) {
try {
const token = this.$store.state.tokens[this.userId];
if (!token) {
alert("用户未登录,请重新登录!");
this.$router.push("/login");
return;
}
const response = await axios.get("http://localhost:8080/teacher/examPaper/getExamPaperQuestions", {
params: { id: examId },
headers: { Authorization: `Bearer ${token}` },
});
if (response.data.code === 200) {
this.examQuestions = response.data.data; // 获取试卷题目
} else {
this.$message.error("获取试卷题目失败");
}
} catch (error) {
console.error("获取试卷题目失败:", error);
this.$message.error("获取试卷题目失败");
}
},
// 将题目添加到试卷
async addQuestionToExam(questionId) {
try {
const token = this.$store.state.tokens[this.userId];
if (!token) {
alert("用户未登录,请重新登录!");
this.$router.push("/login");
return;
}
const response = await axios.get("http://localhost:8080/examcreate/addQuestionByExamPaper", {
params:{
pid: this.selectedExam.id,
id: questionId,
},
headers: { Authorization: `Bearer ${token}` },
});
console.log(response.data);
if (response.data.code === 200 && response.data.data > 0) {
this.$message.success("题目已添加到试卷");
this.fetchExamQuestions(this.selectedExam.id); // 刷新试卷题目
this.isAddQuestionDialogVisible = false; // 关闭对话框
} else {
this.$message.error("添加失败");
}
} catch (error) {
console.error("添加题目失败:", error);
this.$message.error("添加题目失败");
}
},
// 打开分发试卷的弹窗
openDistributionDialog(exam) {
this.selectedExam = exam;
this.fetchClassList(exam.id);
this.isDistributionDialogVisible = true;
},
// 获取班级列表
async fetchClassList(testid) {
try{
const token = this.$store.state.tokens[this.userId];
if (!token) {
alert("用户未登录,请重新登录!");
this.$router.push("/login");
return;
}
const response = await axios.get("http://localhost:8080/teacher/examPaper/selectClassRelease",{
params:{testid:testid},
headers:{Authorization:`Bearer ${token}`}
});
if(response.data.code===200){
this.classList = response.data.data;
}
}catch (error){
alert("用户未登录,请重新登录!");
this.$router.push("/login");
return;
}
},
// 更新班级分发状态
updateStatus(classInfo) {
console.log("更新状态:", classInfo.className, "为", classInfo.status);
},
// 向特定班级分发试卷
async distributeExam(testid,classInfo) {
try {
const token = this.$store.state.tokens[this.userId];
if (!token) {
alert("用户未登录,请重新登录!");
this.$router.push("/login");
return;
}
console.log("class1",classInfo.class1);
const response = await axios.post("http://localhost:8080/teacher/examPaper/addExamPaper", {
id: testid, // 直接在请求体中传递
grade: classInfo.grade,
class1: classInfo.class1
}, {
headers: { Authorization: `Bearer ${token}` }
});
console.log("response",response);
if(response.data.code===200){
this.$message.success("分发成功!");
this.fetchClassList(testid);
}else{
this.$message.error("分发失败!");
}
}catch (error){
console.log("数据异常"+error);
}
},
// 获取试卷列表
async fetchExams() {
try {
const token = this.$store.state.tokens[this.userId];
if (!token) {
alert("用户未登录,请重新登录!");
this.$router.push("/login");
return;
}
const response = await axios.get("http://localhost:8080/teacher/examPaper/getExamPaper",{
params: {
pageNum: this.currentPage,
pageSize: this.pageSize,
},
headers: {
Authorization: `Bearer ${token}`,
}
});
if(response.data.code===200){
this.exams = response.data.data.records;
}else{
this.$message.error("获取数据异常");
}
}catch(error) {
console.error("获取试卷列表失败:", error);
}
},
// 处理分页页码变化
handlePageChange(page) {
this.currentPage = page;
this.fetchExams(); // 获取新的页码数据
},
openNewExamDialog() {
this.isNewExamDialogVisible = true;
},
async createExam() {
try {
const token = this.$store.state.tokens[this.userId];
if (!token) {
alert("用户未登录,请重新登录!");
this.$router.push("/login");
return;
}
const response = await axios.post("http://localhost:8080/teacher/examPaper/newExamPaper", this.newExamForm,{
headers: { Authorization: `Bearer ${token}` },
});
console.log(response.data);
if(response.data.code === 200 && response.data.data > 0){
this.$message.success("试卷创建成功");
this.fetchExams();
this.isNewExamDialogVisible = false;
}else{
this.$message.error("试卷创建失败");
}
} catch (error) {
console.error("Error creating exam:", error);
}
},
},
created() {
this.userId = this.$route.query.userId;
this.fetchExams(); // 页面加载时获取试卷列表
},
};
</script>
<style scoped lang="scss">
.el-table {
margin-top: 20px;
}
/* */
.el-dialog {
border-radius: 10px;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
.el-dialog__header {
background-color: #409EFF;
color: white;
border-radius: 10px 10px 0 0;
font-weight: bold;
}
}
/* */
.exam-table-container {
margin-top: 20px;
}
/* */
.option-row {
margin-bottom: 10px;
}
/* */
.option-tag {
border-radius: 20px;
font-size: 14px;
}
.no-option-tag {
background-color: #f56c6c;
color: white;
font-size: 14px;
}
/* */
.dialog-footer {
text-align: right;
padding: 15px;
}
</style>