|
|
|
@ -1,12 +1,12 @@
|
|
|
|
|
<template>
|
|
|
|
|
<el-container style="min-height: 100vh">
|
|
|
|
|
<!-- 左侧边栏 -->
|
|
|
|
|
<el-aside :width="sideWidth + 'px'" style="background-color: #f4f6f9; box-shadow: 2px 0 6px rgba(0, 21, 41, 0.1)">
|
|
|
|
|
<el-aside :width="sideWidth + 'px'" style="background-color: #f4f6f9; box-shadow: 2px 0 6px rgba(0, 21, 41, 0.1); position: fixed; height: 100vh;">
|
|
|
|
|
<Aside :isCollapse="isCollapse" :logoTextShow="logoTextShow" />
|
|
|
|
|
</el-aside>
|
|
|
|
|
|
|
|
|
|
<!-- 主内容 -->
|
|
|
|
|
<el-container>
|
|
|
|
|
<el-container style="margin-left: 200px;">
|
|
|
|
|
<!-- 顶部 Header -->
|
|
|
|
|
<el-header style="border-bottom: 1px solid #e0e0e0; background-color: #ffffff; padding: 10px;">
|
|
|
|
|
<Header :collapseBtnClass="collapseBtnClass" :collapse="collapse" />
|
|
|
|
@ -18,25 +18,34 @@
|
|
|
|
|
<el-row gutter={20} class="filter-row">
|
|
|
|
|
<!-- 学科筛选 -->
|
|
|
|
|
<el-col :span="7">
|
|
|
|
|
<el-select v-model="selectedSubject" placeholder="选择学科" @change="filterQuestions" class="filter-item">
|
|
|
|
|
<el-select v-model="selectedSubject" :placeholder="getPlaceholder('subject')" @change="fetchQuestions" class="filter-item">
|
|
|
|
|
<el-option label="数学" value="数学" />
|
|
|
|
|
<el-option label="语文" value="语文" />
|
|
|
|
|
<el-option label="英语" value="英语" />
|
|
|
|
|
<el-option label="物理" value="物理" />
|
|
|
|
|
<el-option label="化学" value="化学" />
|
|
|
|
|
<el-option label="无" value="" />
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-col>
|
|
|
|
|
|
|
|
|
|
<!-- 题型筛选 -->
|
|
|
|
|
<el-col :span="7">
|
|
|
|
|
<el-select v-model="selectedType" placeholder="选择题型" @change="filterQuestions" class="filter-item">
|
|
|
|
|
<el-select v-model="selectedType" :placeholder="getPlaceholder('type')" @change="fetchQuestions" class="filter-item">
|
|
|
|
|
<el-option label="单选题" value="1" />
|
|
|
|
|
<el-option label="多选题" value="2" />
|
|
|
|
|
<el-option label="填空题" value="3" />
|
|
|
|
|
<el-option label="判断题" value="4" />
|
|
|
|
|
<el-option label="解答题" value="5" />
|
|
|
|
|
<el-option label="无" value="" />
|
|
|
|
|
<el-option label="解答题" value="4" />
|
|
|
|
|
<el-option label="判断题" value="5" />
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-col>
|
|
|
|
|
|
|
|
|
|
<!-- 难度筛选 -->
|
|
|
|
|
<el-col :span="7">
|
|
|
|
|
<el-select v-model="selectedDifficulty" :placeholder="getPlaceholder('difficulty')" @change="fetchQuestions" class="filter-item">
|
|
|
|
|
<el-option label="1" value="1" />
|
|
|
|
|
<el-option label="2" value="2" />
|
|
|
|
|
<el-option label="3" value="3" />
|
|
|
|
|
<el-option label="4" value="4" />
|
|
|
|
|
<el-option label="5" value="5" />
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-col>
|
|
|
|
|
|
|
|
|
@ -45,7 +54,7 @@
|
|
|
|
|
<el-button type="primary" @click="resetFilters" class="reset-btn">重置</el-button>
|
|
|
|
|
<el-button
|
|
|
|
|
type="primary"
|
|
|
|
|
@click="addQuestion"
|
|
|
|
|
@click="openDialog"
|
|
|
|
|
icon="el-icon-plus"
|
|
|
|
|
:loading="isAddingQuestion"
|
|
|
|
|
class="add-btn"
|
|
|
|
@ -60,37 +69,37 @@
|
|
|
|
|
<el-spin v-if="loading" size="large" />
|
|
|
|
|
|
|
|
|
|
<!-- 题目列表展示 -->
|
|
|
|
|
<el-list v-if="!loading && filteredQuestions.length > 0">
|
|
|
|
|
<el-list v-if="!loading && questionList.length > 0">
|
|
|
|
|
<el-list-item
|
|
|
|
|
v-for="(question, index) in filteredQuestions"
|
|
|
|
|
:key="question.id"
|
|
|
|
|
class="question-item"
|
|
|
|
|
v-for="(question, index) in questionList"
|
|
|
|
|
:key="question.id"
|
|
|
|
|
class="question-item"
|
|
|
|
|
>
|
|
|
|
|
<div class="question-item-content">
|
|
|
|
|
<div class="question-title-container">
|
|
|
|
|
<span class="question-title">{{ question.id }}</span>
|
|
|
|
|
<div class="button-group">
|
|
|
|
|
<el-button
|
|
|
|
|
type="info"
|
|
|
|
|
icon="el-icon-view"
|
|
|
|
|
circle
|
|
|
|
|
@click="previewQuestion(question)"
|
|
|
|
|
class="preview-button"
|
|
|
|
|
type="info"
|
|
|
|
|
icon="el-icon-view"
|
|
|
|
|
circle
|
|
|
|
|
@click="previewQuestion(question)"
|
|
|
|
|
class="preview-button"
|
|
|
|
|
/>
|
|
|
|
|
<el-button
|
|
|
|
|
type="danger"
|
|
|
|
|
icon="el-icon-delete"
|
|
|
|
|
circle
|
|
|
|
|
@click="deleteQuestion(index)"
|
|
|
|
|
class="delete-button"
|
|
|
|
|
type="danger"
|
|
|
|
|
icon="el-icon-delete"
|
|
|
|
|
circle
|
|
|
|
|
@click="showDeleteConfirmation(question.id)"
|
|
|
|
|
class="delete-button"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="question-content">
|
|
|
|
|
<p>{{ question.content }}</p>
|
|
|
|
|
<div class="question-meta">
|
|
|
|
|
<span class="subject-type">学科类型: {{ question.subject }}</span>
|
|
|
|
|
<span class="question-difficulty">难度: {{ question.difficulty }}</span>
|
|
|
|
|
<span class="subject-type">学科类型: {{ question.subject }} </span>
|
|
|
|
|
<span class="question-difficulty">难度: {{ question.difficulty }} </span>
|
|
|
|
|
<span class="created-at">创建时间: {{ question.createtime }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
@ -100,16 +109,38 @@
|
|
|
|
|
|
|
|
|
|
<!-- 分页部分 -->
|
|
|
|
|
<el-pagination
|
|
|
|
|
v-if="!loading && totalQuestions > 0"
|
|
|
|
|
:current-page="currentPage"
|
|
|
|
|
:page-size="pageSize"
|
|
|
|
|
:total="totalQuestions"
|
|
|
|
|
@current-change="handlePageChange"
|
|
|
|
|
layout="total, prev, pager, next, jumper"
|
|
|
|
|
v-if="!loading && totalQuestions > 0"
|
|
|
|
|
:current-page="currentPage"
|
|
|
|
|
:page-size="pageSize"
|
|
|
|
|
:total="totalQuestions < pageSize ? pageSize : totalQuestions"
|
|
|
|
|
@current-change="handlePageChange"
|
|
|
|
|
layout="prev, pager, next, jumper"
|
|
|
|
|
style="text-align: right; margin-top: 20px;"
|
|
|
|
|
/>
|
|
|
|
|
</el-main>
|
|
|
|
|
</el-container>
|
|
|
|
|
|
|
|
|
|
<!-- 删除确认弹窗 -->
|
|
|
|
|
<el-dialog
|
|
|
|
|
title="确认删除"
|
|
|
|
|
:visible.sync="deleteDialogVisible"
|
|
|
|
|
width="50%"
|
|
|
|
|
>
|
|
|
|
|
<p>该问题已经出现在以下试卷中,删除该问题将影响这些试卷:</p>
|
|
|
|
|
<!-- 列出相关的试卷 -->
|
|
|
|
|
<el-table :data="papersToDelete" style="width: 100%">
|
|
|
|
|
<el-table-column prop="id" label="试卷编号" />
|
|
|
|
|
<el-table-column prop="subject" label="学科" />
|
|
|
|
|
<el-table-column prop="name" label="试卷名称" />
|
|
|
|
|
</el-table>
|
|
|
|
|
<p>注:删除已经被调用的题目,相应的试卷中的题目也会被删除</p>
|
|
|
|
|
<span slot="footer" class="dialog-footer">
|
|
|
|
|
<el-button type="success" @click="deleteDialogVisible = false">取消</el-button>
|
|
|
|
|
<el-button type="danger" @click="deleteQuestion()">确认删除</el-button>
|
|
|
|
|
</span>
|
|
|
|
|
</el-dialog>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 预览弹窗 -->
|
|
|
|
|
<el-dialog
|
|
|
|
|
title="预览题目"
|
|
|
|
@ -117,7 +148,7 @@
|
|
|
|
|
width="50%"
|
|
|
|
|
:before-close="handleClosePreview"
|
|
|
|
|
>
|
|
|
|
|
<div class="question-preview">
|
|
|
|
|
<div class="question-preview">
|
|
|
|
|
<p><strong>题目ID:</strong> {{ previewQuestionData.id }}</p>
|
|
|
|
|
<p><strong>题目内容:</strong> {{ previewQuestionData.content }}</p>
|
|
|
|
|
<div v-if="previewQuestionData.chance && previewQuestionData.chance.length > 0">
|
|
|
|
@ -130,14 +161,126 @@
|
|
|
|
|
</el-col>
|
|
|
|
|
</el-row>
|
|
|
|
|
</div>
|
|
|
|
|
<p><strong>答案:</strong> {{ previewQuestionData.answer }}</p>
|
|
|
|
|
<p><strong>学科类型:</strong> {{ previewQuestionData.subject }}</p>
|
|
|
|
|
<p><strong>难度:</strong> {{ previewQuestionData.difficulty }}</p>
|
|
|
|
|
<p><strong>创建时间:</strong> {{ previewQuestionData.createtime | formatDate }}</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<span slot="footer" class="dialog-footer">
|
|
|
|
|
<el-button @click="previewVisible = false">关闭</el-button>
|
|
|
|
|
</span>
|
|
|
|
|
</el-dialog>
|
|
|
|
|
|
|
|
|
|
<!-- 弹窗 -->
|
|
|
|
|
<el-dialog
|
|
|
|
|
title="添加题目"
|
|
|
|
|
:visible.sync="dialogVisible"
|
|
|
|
|
width="50%"
|
|
|
|
|
@close="resetForm"
|
|
|
|
|
>
|
|
|
|
|
<el-form :model="form" ref="form">
|
|
|
|
|
<!-- 题目类型 -->
|
|
|
|
|
<el-form-item label="题目类型" :label-width="'100px'">
|
|
|
|
|
<el-select v-model="form.questiontype" placeholder="选择题目类型">
|
|
|
|
|
<el-option label="单选题" :value="1"></el-option>
|
|
|
|
|
<el-option label="多选题" :value="2"></el-option>
|
|
|
|
|
<el-option label="填空题" :value="3"></el-option>
|
|
|
|
|
<el-option label="解答题" :value="4"></el-option>
|
|
|
|
|
<el-option label="判断题" :value="5"></el-option>
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
|
|
<!-- 学科 -->
|
|
|
|
|
<el-form-item label="学科" :label-width="'100px'">
|
|
|
|
|
<el-select v-model="form.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="分数" :label-width="'100px'">
|
|
|
|
|
<el-input v-model="form.score" placeholder="请输入分数" style="width: 207.22px;" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
|
|
<!-- 难度 -->
|
|
|
|
|
<el-form-item label="难度" :label-width="'100px'">
|
|
|
|
|
<el-select v-model="form.difficulty" placeholder="选择难度">
|
|
|
|
|
<el-option label="1" value="1"></el-option>
|
|
|
|
|
<el-option label="2" value="2"></el-option>
|
|
|
|
|
<el-option label="3" value="3"></el-option>
|
|
|
|
|
<el-option label="4" value="4"></el-option>
|
|
|
|
|
<el-option label="5" value="5"></el-option>
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
|
|
<!-- 题目内容 -->
|
|
|
|
|
<el-form-item label="题目内容" :label-width="'100px'">
|
|
|
|
|
<el-input v-model="form.content" placeholder="请输入题目内容"></el-input>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
|
|
<!-- 单选/多选题选项 -->
|
|
|
|
|
<template v-if="form.questiontype === 1 || form.questiontype === 2">
|
|
|
|
|
<el-form-item label="选项" :label-width="'100px'">
|
|
|
|
|
<div v-for="(chance, index) in form.chance" :key="index" class="option-item">
|
|
|
|
|
<el-row gutter={10}>
|
|
|
|
|
<!-- 选项标识,模拟按钮样式 -->
|
|
|
|
|
<el-col :span="2">
|
|
|
|
|
<span
|
|
|
|
|
class="option-label"
|
|
|
|
|
style="height: 32px; line-height: 32px; padding: 0 15px; background-color: #409EFF; color: white; border-radius: 4px; display: inline-block; text-align: center;">
|
|
|
|
|
{{ chance.label }}
|
|
|
|
|
</span>
|
|
|
|
|
</el-col>
|
|
|
|
|
<!-- 选项内容输入框 -->
|
|
|
|
|
<el-col :span="22">
|
|
|
|
|
<el-input
|
|
|
|
|
v-model="chance.text"
|
|
|
|
|
placeholder="选项内容"
|
|
|
|
|
style="height: 32px; line-height: 32px; padding: 0 10px 0 20px; box-sizing: border-box;" />
|
|
|
|
|
</el-col>
|
|
|
|
|
</el-row>
|
|
|
|
|
</div>
|
|
|
|
|
<el-button @click="addOption" type="text">+ 添加选项</el-button>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<!-- 选择题答案 -->
|
|
|
|
|
<el-form-item label="选择答案" :label-width="'100px'">
|
|
|
|
|
<el-select v-model="form.answer" multiple placeholder="选择正确答案">
|
|
|
|
|
<el-option v-for="(chance, index) in form.chance" :key="index" :label="chance.label" :value="chance.label" />
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<!-- 判断题答案 -->
|
|
|
|
|
<template v-if="form.questiontype === 5">
|
|
|
|
|
<el-form-item label="答案" :label-width="'100px'">
|
|
|
|
|
<el-select v-model="form.answer" placeholder="选择答案">
|
|
|
|
|
<el-option label="正确" value="T"></el-option>
|
|
|
|
|
<el-option label="错误" value="F"></el-option>
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<!-- 填空题/解答题答案 -->
|
|
|
|
|
<template v-if="form.questiontype === 3 || form.questiontype === 4">
|
|
|
|
|
<el-form-item label="答案" :label-width="'100px'">
|
|
|
|
|
<el-input v-model="form.answer" placeholder="请输入答案"></el-input>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<!-- 解释 -->
|
|
|
|
|
<el-form-item label="解释" :label-width="'100px'">
|
|
|
|
|
<el-input type="textarea" v-model="form.analysis" placeholder="请输入解释" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-form>
|
|
|
|
|
|
|
|
|
|
<span slot="footer" class="dialog-footer">
|
|
|
|
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
|
|
|
|
<el-button type="primary" @click="submitForm">确 定</el-button>
|
|
|
|
|
</span>
|
|
|
|
|
</el-dialog>
|
|
|
|
|
|
|
|
|
|
</el-container>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
@ -155,18 +298,38 @@ export default {
|
|
|
|
|
isCollapse: false,
|
|
|
|
|
sideWidth: 200,
|
|
|
|
|
logoTextShow: true,
|
|
|
|
|
questionList: [],
|
|
|
|
|
filteredQuestions: [],
|
|
|
|
|
questionList: [], // 原始数据
|
|
|
|
|
filteredQuestions: [], // 筛选后的数据
|
|
|
|
|
newQuestion: "",
|
|
|
|
|
isAddingQuestion: false,
|
|
|
|
|
currentPage: 1,
|
|
|
|
|
pageSize: 10,
|
|
|
|
|
totalQuestions: 0,
|
|
|
|
|
loading: true,
|
|
|
|
|
currentPage: 1, // 当前页码
|
|
|
|
|
pageSize: 10, // 每页显示的数据数量
|
|
|
|
|
totalQuestions: 0, // 总题目数量
|
|
|
|
|
loading: true, // 加载中状态
|
|
|
|
|
previewVisible: false,
|
|
|
|
|
previewQuestionData: {},
|
|
|
|
|
selectedSubject: "",
|
|
|
|
|
selectedType: "",
|
|
|
|
|
selectedDifficulty: "", // 添加难度筛选
|
|
|
|
|
deleteDialogVisible: false,//删除窗口
|
|
|
|
|
papersToDelete: [],//删除题目相关的试卷
|
|
|
|
|
deleteId: "",
|
|
|
|
|
form: {
|
|
|
|
|
questiontype: 1, // 默认是单选题
|
|
|
|
|
subject: '', // 学科
|
|
|
|
|
difficulty: 3, // 难度,默认中等
|
|
|
|
|
content: '', // 题目内容
|
|
|
|
|
chance: [
|
|
|
|
|
{ label: 'A', text: '' },
|
|
|
|
|
{ label: 'B', text: '' },
|
|
|
|
|
{ label: 'C', text: '' },
|
|
|
|
|
{ label: 'D', text: '' }
|
|
|
|
|
], // 选项
|
|
|
|
|
answer: '', // 判断题答案(T/F)
|
|
|
|
|
analysis: '', // 解释
|
|
|
|
|
score: 3,//分数,默认是3
|
|
|
|
|
},
|
|
|
|
|
dialogVisible: false,//添加弹窗
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
@ -176,7 +339,7 @@ export default {
|
|
|
|
|
this.collapseBtnClass = this.isCollapse ? "el-icon-s-unfold" : "el-icon-s-fold";
|
|
|
|
|
this.logoTextShow = !this.isCollapse;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
//预览
|
|
|
|
|
previewQuestion(question) {
|
|
|
|
|
this.previewQuestionData = question;
|
|
|
|
|
this.previewVisible = true;
|
|
|
|
@ -187,8 +350,97 @@ export default {
|
|
|
|
|
this.fetchQuestions();
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
async fetchQuestions() {
|
|
|
|
|
// 打开弹窗
|
|
|
|
|
openDialog() {
|
|
|
|
|
this.dialogVisible = true;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 重置表单内容
|
|
|
|
|
resetForm() {
|
|
|
|
|
this.form.questiontype = 1;
|
|
|
|
|
this.form.subject = '';
|
|
|
|
|
this.form.difficulty = 3;
|
|
|
|
|
this.form.content = '';
|
|
|
|
|
this.form.chance = [
|
|
|
|
|
{ label: 'A', text: '' },
|
|
|
|
|
{ label: 'B', text: '' },
|
|
|
|
|
{ label: 'C', text: '' },
|
|
|
|
|
{ label: 'D', text: '' }
|
|
|
|
|
];
|
|
|
|
|
this.form.answer = '';
|
|
|
|
|
this.form.analysis = '';
|
|
|
|
|
this.form.score = 3;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 添加选项
|
|
|
|
|
addOption() {
|
|
|
|
|
// 获取当前选项的最后一个字母,并推算出下一个字母
|
|
|
|
|
const lastOption = this.form.chance[this.form.chance.length - 1];
|
|
|
|
|
const nextLabel = String.fromCharCode(lastOption.label.charCodeAt(0) + 1); // 通过字符编码生成下一个字母
|
|
|
|
|
this.form.chance.push({ label: nextLabel, text: '' });
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 提交表单
|
|
|
|
|
async submitForm() {
|
|
|
|
|
try {
|
|
|
|
|
// 调用后端 API 查询该问题是否在试卷中被引用
|
|
|
|
|
const token = this.$store.state.tokens[this.userId];
|
|
|
|
|
if (!token) {
|
|
|
|
|
alert("用户未登录,请重新登录!");
|
|
|
|
|
this.$router.push("/login");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// 将 answer 转换为字符串格式(逗号分隔)
|
|
|
|
|
const answer = Array.isArray(this.form.answer) ? this.form.answer.join('') : this.form.answer;
|
|
|
|
|
let chance = null;
|
|
|
|
|
if(this.form.questiontype === 1 || this.form.questiontype === 2){
|
|
|
|
|
// 将 chance 转换为纯数组
|
|
|
|
|
chance = JSON.parse(JSON.stringify(this.form.chance));
|
|
|
|
|
}
|
|
|
|
|
// 构建请求体,处理表单数据
|
|
|
|
|
const requestBody = {
|
|
|
|
|
questiontype: this.form.questiontype,
|
|
|
|
|
subject: this.form.subject,
|
|
|
|
|
difficulty: this.form.difficulty,
|
|
|
|
|
content: this.form.content,
|
|
|
|
|
chance: chance,
|
|
|
|
|
answer: answer,
|
|
|
|
|
analysis: this.form.analysis,
|
|
|
|
|
score: this.form.score,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
console.log('提交的题目数据:', requestBody);
|
|
|
|
|
|
|
|
|
|
const response = await axios.post("http://localhost:8080/examcreate/addQuestion", requestBody, {
|
|
|
|
|
headers: {
|
|
|
|
|
Authorization: `Bearer ${token}`,
|
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
console.log('后端返回的数据:', response);
|
|
|
|
|
|
|
|
|
|
if(response.data.code === 200 && response.data.data===1){
|
|
|
|
|
this.$message.success("添加成功");
|
|
|
|
|
this.dialogVisible = false;
|
|
|
|
|
}else{
|
|
|
|
|
this.$message.error("添加失败");
|
|
|
|
|
}
|
|
|
|
|
}catch(error){
|
|
|
|
|
console.error("添加失败", error);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 显示删除确认弹窗
|
|
|
|
|
showDeleteConfirmation(questionId) {
|
|
|
|
|
this.deleteId = questionId;
|
|
|
|
|
this.deleteDialogVisible = true; // 显示弹窗
|
|
|
|
|
this.checkExamPaperByQuestionId(questionId);//查询相关的试卷
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
async checkExamPaperByQuestionId(questionId) {
|
|
|
|
|
try {
|
|
|
|
|
// 调用后端 API 查询该问题是否在试卷中被引用
|
|
|
|
|
const token = this.$store.state.tokens[this.userId];
|
|
|
|
|
if (!token) {
|
|
|
|
|
alert("用户未登录,请重新登录!");
|
|
|
|
@ -196,8 +448,69 @@ export default {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const response = await axios.get("http://localhost:8080/examcreate/selectExamPaperByQuestionsId", {
|
|
|
|
|
params: { id: questionId },
|
|
|
|
|
headers: {
|
|
|
|
|
Authorization: `Bearer ${token}`,
|
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (response.data.code === 200) {
|
|
|
|
|
this.papersToDelete = response.data.data; // 获取到相关试卷的列表
|
|
|
|
|
} else {
|
|
|
|
|
this.$message.error("检查失败,无法获取相关数据");
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("查询失败", error);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
//删除
|
|
|
|
|
async deleteQuestion(){
|
|
|
|
|
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/deleteQuestions", {
|
|
|
|
|
params: {
|
|
|
|
|
id: this.deleteId,
|
|
|
|
|
},
|
|
|
|
|
headers: {
|
|
|
|
|
Authorization: `Bearer ${token}`,
|
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if(response.data.code==200){
|
|
|
|
|
this.$message.success("删除成功");
|
|
|
|
|
this.fetchQuestions();
|
|
|
|
|
this.deleteDialogVisible = false; // 显示弹窗
|
|
|
|
|
}else{
|
|
|
|
|
this.$message.error("删除失败");
|
|
|
|
|
}
|
|
|
|
|
}catch (error) {
|
|
|
|
|
console.error("获取数据失败", error);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 修改:每次筛选条件变化都重新请求数据
|
|
|
|
|
async fetchQuestions() {
|
|
|
|
|
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/selectList", {
|
|
|
|
|
params: {
|
|
|
|
|
subject: this.selectedSubject,
|
|
|
|
|
questiontype: this.selectedType,
|
|
|
|
|
difficulty: this.selectedDifficulty,
|
|
|
|
|
pagenum: this.currentPage,
|
|
|
|
|
pagesize: this.pageSize,
|
|
|
|
|
},
|
|
|
|
@ -210,7 +523,6 @@ export default {
|
|
|
|
|
if (response.data.code === 200) {
|
|
|
|
|
this.questionList = response.data.data.records;
|
|
|
|
|
this.totalQuestions = response.data.data.total;
|
|
|
|
|
this.filterQuestions();
|
|
|
|
|
} else {
|
|
|
|
|
this.$message.error("获取数据失败");
|
|
|
|
|
}
|
|
|
|
@ -221,81 +533,64 @@ export default {
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
filterQuestions() {
|
|
|
|
|
let filteredQuestions = this.questionList;
|
|
|
|
|
|
|
|
|
|
if (this.selectedSubject) {
|
|
|
|
|
filteredQuestions = filteredQuestions.filter(item => item.subject === this.selectedSubject);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (this.selectedType) {
|
|
|
|
|
filteredQuestions = filteredQuestions.filter(item => item.questiontype === parseInt(this.selectedType));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.filteredQuestions = filteredQuestions;
|
|
|
|
|
this.totalQuestions = filteredQuestions.length;
|
|
|
|
|
this.currentPage = 1;
|
|
|
|
|
this.fetchQuestions();
|
|
|
|
|
this.loading = false;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 重置筛选
|
|
|
|
|
resetFilters() {
|
|
|
|
|
this.selectedSubject = "";
|
|
|
|
|
this.selectedType = "";
|
|
|
|
|
this.filterQuestions();
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
deleteQuestion(index) {
|
|
|
|
|
this.filteredQuestions.splice(index, 1);
|
|
|
|
|
this.totalQuestions -= 1;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
async addQuestion() {
|
|
|
|
|
if (!this.newQuestion) {
|
|
|
|
|
this.$message.warning("请输入题目内容");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
this.isAddingQuestion = true;
|
|
|
|
|
try {
|
|
|
|
|
const response = await axios.post("http://localhost:8080/examcreate/addQuestion", {
|
|
|
|
|
content: this.newQuestion,
|
|
|
|
|
});
|
|
|
|
|
if (response.data.code === 200) {
|
|
|
|
|
this.newQuestion = "";
|
|
|
|
|
this.fetchQuestions();
|
|
|
|
|
} else {
|
|
|
|
|
this.$message.error("添加题目失败");
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("添加题目失败", error);
|
|
|
|
|
this.$message.error("添加题目失败");
|
|
|
|
|
} finally {
|
|
|
|
|
this.isAddingQuestion = false;
|
|
|
|
|
}
|
|
|
|
|
this.selectedDifficulty = "";
|
|
|
|
|
this.fetchQuestions();
|
|
|
|
|
this.currentPage = 1;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
handleClosePreview() {
|
|
|
|
|
this.previewVisible = false;
|
|
|
|
|
this.previewQuestionData = {};
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 获取筛选框提示信息
|
|
|
|
|
getPlaceholder(field) {
|
|
|
|
|
const placeholders = {
|
|
|
|
|
subject: "选择学科",
|
|
|
|
|
type: "选择题型",
|
|
|
|
|
difficulty: "选择难度",
|
|
|
|
|
};
|
|
|
|
|
return placeholders[field] || "请选择";
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
created() {
|
|
|
|
|
this.userId = this.$route.query.userId;
|
|
|
|
|
this.fetchQuestions();
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
filters: {
|
|
|
|
|
formatDate(value) {
|
|
|
|
|
if (!value) return '';
|
|
|
|
|
const date = new Date(value);
|
|
|
|
|
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')} ${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`;
|
|
|
|
|
},
|
|
|
|
|
this.fetchQuestions(); // 初始化时获取题目数据
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
|
|
|
|
|
.option-label {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
align-items: center;
|
|
|
|
|
padding: 5px 15px;
|
|
|
|
|
background-color: #409EFF;
|
|
|
|
|
color: white;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
line-height: 30px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.el-input {
|
|
|
|
|
height: 32px;
|
|
|
|
|
padding: 5px 0; /* 确保输入框的上下内边距和标识的对齐 */
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
line-height: 30px; /* 设置输入框的行高 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.option-item {
|
|
|
|
|
margin-bottom: 10px;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center; /* 确保内容和标识在垂直方向对齐 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.filter-container {
|
|
|
|
|
margin-bottom: 20px;
|
|
|
|
|
}
|
|
|
|
@ -323,7 +618,6 @@ export default {
|
|
|
|
|
.question-item {
|
|
|
|
|
margin-bottom: 15px;
|
|
|
|
|
padding: 15px;
|
|
|
|
|
//border: 1px solid #ddd;
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|