|
|
@@ -65,6 +65,8 @@
|
|
|
</template>
|
|
|
<template #download="{row}">
|
|
|
<el-button type="primary" link @click="handleDownload(row.paperId, row.paperName)" v-hasPermi="['learn:paper:download']">下载</el-button>
|
|
|
+ <!-- <el-button type="success" link @click="handleShowPaperQuestion(row.paperId)">题目</el-button> -->
|
|
|
+ <el-button type="warning" link @click="handleSendPaper(row)">发送</el-button>
|
|
|
</template>
|
|
|
</Table>
|
|
|
|
|
|
@@ -108,12 +110,87 @@
|
|
|
</div>
|
|
|
</div>
|
|
|
</el-dialog>
|
|
|
+
|
|
|
+ <!-- 试卷题目弹窗 -->
|
|
|
+ <el-dialog v-model="paperQuestionDialogVisible" title="试卷题目" width="90%" destroy-on-close>
|
|
|
+ <div style="height: 70vh; overflow: auto;">
|
|
|
+ <QuestionsComponent v-if="paperQuestionDialogVisible" :paper-id="currentPaperId" :hide-actions="true" />
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
+ <!-- 发送试卷弹窗 -->
|
|
|
+ <el-dialog v-model="sendPaperDialogVisible" title="发送试卷" width="60%" destroy-on-close>
|
|
|
+ <el-form :model="sendPaperForm" label-width="100px">
|
|
|
+ <el-form-item label="学校">
|
|
|
+ <el-select
|
|
|
+ v-model="sendPaperForm.schoolId"
|
|
|
+ placeholder="请选择学校"
|
|
|
+ clearable
|
|
|
+ filterable
|
|
|
+ style="width: 100%"
|
|
|
+ @change="handleSchoolChange"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="school in schoolList"
|
|
|
+ :key="school.id"
|
|
|
+ :label="school.name"
|
|
|
+ :value="school.id"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="班级">
|
|
|
+ <el-select
|
|
|
+ v-model="sendPaperForm.classId"
|
|
|
+ placeholder="请先选择学校"
|
|
|
+ clearable
|
|
|
+ filterable
|
|
|
+ style="width: 100%"
|
|
|
+ :disabled="!sendPaperForm.schoolId"
|
|
|
+ @change="handleClassChange"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="cls in classList"
|
|
|
+ :key="cls.classId"
|
|
|
+ :label="cls.name"
|
|
|
+ :value="cls.classId"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="学生列表">
|
|
|
+ <div style="max-height: 400px; overflow-y: auto; border: 1px solid #dcdfe6; border-radius: 4px; padding: 10px;">
|
|
|
+ <el-checkbox-group v-model="selectedStudentIds" v-loading="studentListLoading">
|
|
|
+ <el-checkbox
|
|
|
+ v-for="student in studentList"
|
|
|
+ :key="student.studentId"
|
|
|
+ :label="student.studentId"
|
|
|
+ style="display: block; margin-bottom: 8px;"
|
|
|
+ >
|
|
|
+ {{ student.studentName || `学生ID: ${student.studentId}` }}
|
|
|
+ </el-checkbox>
|
|
|
+ </el-checkbox-group>
|
|
|
+ <div v-if="!studentListLoading && studentList.length === 0" style="text-align: center; color: #909399; padding: 20px;">
|
|
|
+ 请先选择学校和班级
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <template #footer>
|
|
|
+ <div class="dialog-footer">
|
|
|
+ <el-button @click="sendPaperDialogVisible = false">取 消</el-button>
|
|
|
+ <el-button type="primary" @click="handleConfirmSend" :loading="sending">确 定</el-button>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
</template>
|
|
|
|
|
|
<script setup name="ListPaperRecords">
|
|
|
-import { ref, computed, getCurrentInstance, onMounted } from 'vue'
|
|
|
+import { ref, computed, getCurrentInstance, onMounted, markRaw } from 'vue'
|
|
|
import { useInjectGlobalLoading } from "@/views/hooks/useGlobalLoading.js"
|
|
|
import { getPapers, getFrontPaperDetail } from "@/api/dz/papers.js"
|
|
|
+import { listPaper_question } from "@/api/learn/paper_question.js"
|
|
|
+import { getAllSchool } from "@/api/dz/school.js"
|
|
|
+import { getClassesBySchoolId } from "@/api/dz/classes.js"
|
|
|
+import { listStudent } from "@/api/learn/student.js"
|
|
|
import { ElMessage } from 'element-plus'
|
|
|
import Table from '@/components/Table/index.vue'
|
|
|
import DictTag from '@/components/DictTag/index.vue'
|
|
|
@@ -122,6 +199,8 @@ import { listToMap } from "@/utils/index.js"
|
|
|
import { useProvidePaperBatchCondition } from "@/views/dz/papers/hooks/usePaperBatchCondition.js"
|
|
|
import { usePaperDownload } from "@/views/dz/papers/hooks/usePaperDownload.js"
|
|
|
import { parseTime } from "@/utils/ruoyi.js"
|
|
|
+import Pagination from '@/components/Pagination/index.vue'
|
|
|
+import QuestionsComponent from '@/views/learn/questions/index.vue'
|
|
|
|
|
|
const { proxy } = getCurrentInstance()
|
|
|
const { exam_type } = proxy.useDict("exam_type")
|
|
|
@@ -165,6 +244,24 @@ const questionList = ref([])
|
|
|
const currentPaperName = ref('')
|
|
|
const currentSubjectName = ref('')
|
|
|
|
|
|
+// 试卷题目弹窗
|
|
|
+const paperQuestionDialogVisible = ref(false)
|
|
|
+const currentPaperId = ref(null)
|
|
|
+
|
|
|
+// 发送试卷弹窗
|
|
|
+const sendPaperDialogVisible = ref(false)
|
|
|
+const sendPaperForm = ref({
|
|
|
+ schoolId: null,
|
|
|
+ classId: null
|
|
|
+})
|
|
|
+const schoolList = ref([])
|
|
|
+const classList = ref([])
|
|
|
+const studentList = ref([])
|
|
|
+const selectedStudentIds = ref([])
|
|
|
+const studentListLoading = ref(false)
|
|
|
+const sending = ref(false)
|
|
|
+const currentPaperRow = ref(null)
|
|
|
+
|
|
|
|
|
|
// 获取题数/总分显示
|
|
|
const getQuestionInfo = (row) => {
|
|
|
@@ -263,6 +360,146 @@ const getOptionLabel = (index) => {
|
|
|
return labels[index] || String(index + 1)
|
|
|
}
|
|
|
|
|
|
+// 显示试卷题目
|
|
|
+const handleShowPaperQuestion = (paperId) => {
|
|
|
+ if (!paperId) {
|
|
|
+ ElMessage.warning('试卷ID不存在')
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ currentPaperId.value = paperId
|
|
|
+ paperQuestionDialogVisible.value = true
|
|
|
+}
|
|
|
+
|
|
|
+// 显示发送试卷弹窗
|
|
|
+const handleSendPaper = (row) => {
|
|
|
+ if (!row || !row.paperId) {
|
|
|
+ ElMessage.warning('试卷信息不存在')
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ currentPaperRow.value = row
|
|
|
+ sendPaperForm.value = {
|
|
|
+ schoolId: null,
|
|
|
+ classId: null
|
|
|
+ }
|
|
|
+ classList.value = []
|
|
|
+ studentList.value = []
|
|
|
+ selectedStudentIds.value = []
|
|
|
+ sendPaperDialogVisible.value = true
|
|
|
+
|
|
|
+ // 加载学校列表
|
|
|
+ loadSchoolList()
|
|
|
+}
|
|
|
+
|
|
|
+// 加载学校列表
|
|
|
+const loadSchoolList = async () => {
|
|
|
+ try {
|
|
|
+ const response = await getAllSchool()
|
|
|
+ if (response && response.data) {
|
|
|
+ schoolList.value = response.data
|
|
|
+ } else {
|
|
|
+ schoolList.value = []
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('加载学校列表失败:', error)
|
|
|
+ ElMessage.error('加载学校列表失败')
|
|
|
+ schoolList.value = []
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 学校变化时加载班级列表
|
|
|
+const handleSchoolChange = async (schoolId) => {
|
|
|
+ sendPaperForm.value.classId = null
|
|
|
+ classList.value = []
|
|
|
+ studentList.value = []
|
|
|
+ selectedStudentIds.value = []
|
|
|
+
|
|
|
+ if (!schoolId) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ const response = await getClassesBySchoolId({ schoolId })
|
|
|
+ if (response && response.data) {
|
|
|
+ classList.value = response.data
|
|
|
+ } else {
|
|
|
+ classList.value = []
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('加载班级列表失败:', error)
|
|
|
+ ElMessage.error('加载班级列表失败')
|
|
|
+ classList.value = []
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 班级变化时加载学生列表
|
|
|
+const handleClassChange = async (classId) => {
|
|
|
+ studentList.value = []
|
|
|
+ selectedStudentIds.value = []
|
|
|
+
|
|
|
+ if (!classId || !sendPaperForm.value.schoolId) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ studentListLoading.value = true
|
|
|
+ try {
|
|
|
+ const response = await listStudent({
|
|
|
+ schoolId: sendPaperForm.value.schoolId,
|
|
|
+ classId: classId,
|
|
|
+ pageNum: 1,
|
|
|
+ pageSize: 1000
|
|
|
+ })
|
|
|
+ if (response && response.rows) {
|
|
|
+ studentList.value = response.rows
|
|
|
+ } else {
|
|
|
+ studentList.value = []
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('加载学生列表失败:', error)
|
|
|
+ ElMessage.error('加载学生列表失败')
|
|
|
+ studentList.value = []
|
|
|
+ } finally {
|
|
|
+ studentListLoading.value = false
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 确认发送
|
|
|
+const handleConfirmSend = async () => {
|
|
|
+ if (!currentPaperRow.value || !currentPaperRow.value.paperId) {
|
|
|
+ ElMessage.warning('试卷信息不存在')
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!sendPaperForm.value.schoolId) {
|
|
|
+ ElMessage.warning('请选择学校')
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!sendPaperForm.value.classId) {
|
|
|
+ ElMessage.warning('请选择班级')
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!selectedStudentIds.value || selectedStudentIds.value.length === 0) {
|
|
|
+ ElMessage.warning('请至少选择一个学生')
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ sending.value = true
|
|
|
+ try {
|
|
|
+ // TODO: 调用发送试卷的API
|
|
|
+ // 这里需要根据实际的API接口来实现
|
|
|
+ ElMessage.success(`试卷已发送给 ${selectedStudentIds.value.length} 个学生`)
|
|
|
+ sendPaperDialogVisible.value = false
|
|
|
+ } catch (error) {
|
|
|
+ console.error('发送试卷失败:', error)
|
|
|
+ ElMessage.error('发送试卷失败')
|
|
|
+ } finally {
|
|
|
+ sending.value = false
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
// 表格列定义
|
|
|
const columns = [
|
|
|
{ label: 'ID', prop: 'id', width: 80 },
|
|
|
@@ -276,7 +513,7 @@ const columns = [
|
|
|
{ label: '题数/总分', prop: 'questionInfo', width: 100, type: 'slot', slotName: 'questionInfo' },
|
|
|
{ label: '时长(分钟)', prop: 'duration', width: 120, type: 'slot', slotName: 'duration' },
|
|
|
{ label: '创建时间', prop: 'createTime', width: 160, type: 'slot', slotName: 'createTime' },
|
|
|
- { label: '操作', prop: 'download', width: 80, type: 'slot', slotName: 'download' }
|
|
|
+ { label: '操作', prop: 'download', width: 150, type: 'slot', slotName: 'download' }
|
|
|
]
|
|
|
|
|
|
// 操作按钮
|