feat(exam): 实现按学生批量生成并下载试题功能
- 增加学生多选功能和生成试题按钮,支持批量操作 - 新增ExamGenerateDialog组件,提供选择年级和难度界面 - 设计后端接口支持多个学生ID,生成对应的试题文档 - 在后端实现批量生成Word文档并压缩打包下载 - 新增StudentDetail业务对象,完善学生信息展示 - 优化了Mapper接口及XML,支持批量查询学生和班级数据 - 提供前端API封装用于调用试题生成和下载服务 - 实现下载失败时的错误处理与提示机制
This commit is contained in:
@@ -35,8 +35,19 @@
|
||||
selectedGradeId }})</el-tag>
|
||||
<el-button type="primary" @click="fetchStudents">查询</el-button>
|
||||
<el-button @click="resetStudentFilters">重置</el-button>
|
||||
<el-button type="success" :disabled="selectedStudentIds.length === 0" @click="showGenerateDialog = true">
|
||||
生成试题
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table :data="students" border class="w-full" v-loading="studentLoading">
|
||||
<el-table
|
||||
ref="studentTableRef"
|
||||
:data="students"
|
||||
border
|
||||
class="w-full"
|
||||
v-loading="studentLoading"
|
||||
@selection-change="onStudentSelectionChange"
|
||||
>
|
||||
<el-table-column type="selection" width="48" />
|
||||
<el-table-column prop="id" label="ID" width="80" />
|
||||
<el-table-column prop="name" label="姓名" min-width="120" />
|
||||
<el-table-column prop="classId" label="班级ID" width="100" />
|
||||
@@ -47,6 +58,11 @@
|
||||
:total="studentTotalCount" :page-size="studentPageSize" :current-page="studentPageNo"
|
||||
@current-change="handleStudentPageChange" @size-change="handleStudentSizeChange" />
|
||||
</div>
|
||||
<ExamGenerateDialog
|
||||
v-model="showGenerateDialog"
|
||||
:student-ids="selectedStudentIds"
|
||||
:default-grade-id="selectedGradeId"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="bg-white dark:bg-gray-800 rounded-lg shadow p-6" v-loading="gradeLoading">
|
||||
@@ -76,6 +92,7 @@ import { ref, onMounted } from 'vue'
|
||||
import { getClassList } from '@/api/class'
|
||||
import { getGradeList } from '@/api/grade'
|
||||
import { getStudentList } from '@/api/student'
|
||||
import ExamGenerateDialog from '@/layouts/components/ExamGenerateDialog.vue'
|
||||
|
||||
const classes = ref([])
|
||||
const pageNo = ref(1)
|
||||
@@ -85,6 +102,7 @@ const loading = ref(false)
|
||||
const classTableRef = ref(null)
|
||||
const selectedClassId = ref(null)
|
||||
const selectedClassTitle = ref('')
|
||||
|
||||
const grades = ref([])
|
||||
const gradePageNo = ref(1)
|
||||
const gradePageSize = ref(10)
|
||||
@@ -93,12 +111,16 @@ const gradeLoading = ref(false)
|
||||
const gradeTableRef = ref(null)
|
||||
const selectedGradeId = ref(null)
|
||||
const selectedGradeTitle = ref('')
|
||||
|
||||
const students = ref([])
|
||||
const studentPageNo = ref(1)
|
||||
const studentPageSize = ref(10)
|
||||
const studentTotalCount = ref(0)
|
||||
const studentLoading = ref(false)
|
||||
const studentName = ref('')
|
||||
const studentTableRef = ref(null)
|
||||
const selectedStudentIds = ref([])
|
||||
const showGenerateDialog = ref(false)
|
||||
|
||||
async function fetchClasses() {
|
||||
loading.value = true
|
||||
@@ -178,6 +200,9 @@ function handleStudentSizeChange(s) {
|
||||
studentPageNo.value = 1
|
||||
fetchStudents()
|
||||
}
|
||||
function onStudentSelectionChange(rows) {
|
||||
selectedStudentIds.value = rows.map(r => r.id)
|
||||
}
|
||||
function onClassRowClick(row) {
|
||||
selectedClassId.value = row.id
|
||||
selectedClassTitle.value = row.title
|
||||
|
||||
Reference in New Issue
Block a user