diff --git a/src/api/monitor/index.ts b/src/api/monitor/index.ts
index 7034f6b..9c03d60 100644
--- a/src/api/monitor/index.ts
+++ b/src/api/monitor/index.ts
@@ -40,6 +40,10 @@ export const MonitorApi = {
deleteMonitor: async (id: number) => {
return await request.delete({ url: `/exam/monitor/delete?id=` + id })
},
+ // 获取学生文件
+ getMonitorStuFileUrl: async (temporaryId: string) => {
+ return await request.get({ url: `/exam/monitor/getMonitorStuFileUrl?temporaryId=` + temporaryId })
+ },
// 导出监控管理 Excel
exportMonitor: async (params) => {
diff --git a/src/views/monitor/monitor/index.vue b/src/views/monitor/monitor/index.vue
index 5f1bbc5..f4ed455 100644
--- a/src/views/monitor/monitor/index.vue
+++ b/src/views/monitor/monitor/index.vue
@@ -1,39 +1,37 @@
-
-
-
-
-
-
- 待考
- 考试中
- 考试完成
-
-
-
+
+
+
+
+
+ 待考
+ 考试中
+ 考试完成
+
+
+
取消
确认
-
-
-
-
- 取消
- 下一步
-
-
+ :close-on-click-modal="false"
+ :show-close="true"
+ @close="handleNextStepCancel"
+ >
+
+
+ 取消
+ 下一步
+
+
@@ -82,10 +80,6 @@
/>
-
-
-
-
-
-
-
+
+
+
-
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
搜索
重置
- 考试状态改变
- 返回上级列表
-
-
+
导出
-
+
-
-
-
+
-
+
@@ -205,24 +203,14 @@
:formatter="dateFormatter"
width="180px"
/>
-
+
(null)
const fixedTaskId = ref('')
// 接收子组件传递的taskId
const handleTaskSelected = (taskId: string) => {
- fixedTaskId.value = taskId
- queryParams.taskId = taskId
+ fixedTaskId.value = taskId
+ queryParams.taskId = taskId
console.log('父组件接收到的taskId:', queryParams.taskId)
}
/** 监控管理 列表 */
defineOptions({ name: 'Monitor' })
// 新增:初始弹框开关
-const initDialogVisible = ref(true);
+const initDialogVisible = ref(true)
// 弹窗开关
const dialogVisible = ref(false)
const message = useMessage() // 消息弹窗
const { t } = useI18n() // 国际化
-const selectedStatus = ref(null);
+const selectedStatus = ref(null)
const loading = ref(true) // 列表的加载中
const list = ref([]) // 列表的数据
const total = ref(0) // 列表的总页数
-const classNameList = ref();
+const classNameList = ref()
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
- monitorId:undefined,
- taskId:'',
+ monitorId: undefined,
+ taskId: '',
username: undefined,
nickname: undefined,
- taskType:undefined,
+ taskType: undefined,
className: undefined,
examStatus: undefined,
score: undefined,
@@ -284,7 +272,7 @@ const queryParams = reactive({
taskName: undefined,
ip: undefined,
remainingTime: [],
- createTime: [],
+ createTime: []
})
const queryFormRef = ref() // 搜索的表单
const exportLoading = ref(false) // 导出的加载中
@@ -293,13 +281,12 @@ const taskTypeyOptions = ref([])
const getList = async () => {
loading.value = true
try {
- queryParams.taskId = fixedTaskId.value
+ queryParams.taskId = fixedTaskId.value
const data = await MonitorApi.getMonitorPage(queryParams)
// queryParams.taskId = ''
list.value = data.list
total.value = data.total
- classNameList.value = await ClassApi.ClassApi.getClassName()
-
+ classNameList.value = await ClassApi.ClassApi.getClassName()
} finally {
loading.value = false
}
@@ -308,41 +295,38 @@ const getList = async () => {
// 打开弹窗
const openDialog = async () => {
- const rows = selections.value;
+ const rows = selections.value
if (!rows.length) {
- message.error('请至少选择一条数据');
- return;
+ message.error('请至少选择一条数据')
+ return
}
-
+
dialogVisible.value = true
- selections.value = rows;
-
+ selections.value = rows
}
const returnTop = async () => {
initDialogVisible.value = true
}
-
-
- /** 表格选中数据 */
-const selections = ref([]);
-const taskList = ref([]);
+/** 表格选中数据 */
+const selections = ref([])
+const taskList = ref([])
const handleSelectionChange = (rows) => {
- selections.value = rows;
+ selections.value = rows
}
const dateFormatterMin = (row, column, cellValue) => {
- if (cellValue == null || isNaN(cellValue)) return '-';
+ if (cellValue == null || isNaN(cellValue)) return '-'
- const hours = Math.floor(cellValue / 3600);
- const minutes = Math.floor((cellValue % 3600) / 60);
- const seconds = cellValue % 60;
+ const hours = Math.floor(cellValue / 3600)
+ const minutes = Math.floor((cellValue % 3600) / 60)
+ const seconds = cellValue % 60
// 补零处理
- const pad = (n) => n.toString().padStart(2, '0');
+ const pad = (n) => n.toString().padStart(2, '0')
- return `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`;
-};
+ return `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`
+}
/** 搜索按钮操作 */
const handleQuery = () => {
@@ -362,28 +346,25 @@ const openForm = (type: string, id?: number) => {
formRef.value.open(type, id)
}
// 提交状态变更
- const confirmChange = async () => {
-
- if (selectedStatus.value === null) {
- ElMessage.error('请选择考试状态');
- return;
- }
-
- const rows = selections.value;
-
- const monitorIds = rows.map((row: any) => row.monitorId);
-
-
- await MonitorApi.updateMonitorStatus({
- monitorIds, // 这是数组
- status: selectedStatus.value // 这是 0,1,2
- });
-
-
- ElMessage.success('考试状态更新成功')
- dialogVisible.value = false
- getList()
+const confirmChange = async () => {
+ if (selectedStatus.value === null) {
+ ElMessage.error('请选择考试状态')
+ return
}
+
+ const rows = selections.value
+
+ const monitorIds = rows.map((row: any) => row.monitorId)
+
+ await MonitorApi.updateMonitorStatus({
+ monitorIds, // 这是数组
+ status: selectedStatus.value // 这是 0,1,2
+ })
+
+ ElMessage.success('考试状态更新成功')
+ dialogVisible.value = false
+ getList()
+}
/** 删除按钮操作 */
const handleDelete = async (id: number) => {
try {
@@ -397,39 +378,67 @@ const handleDelete = async (id: number) => {
} catch {}
}
-const selectedRows = ref([]);
+const downloadFile = async (row: any) => {
+ const res = await MonitorApi.getMonitorStuFileUrl(row.temporaryId)
+ console.log(res)
+ const url = res
+ try {
+ const response = await fetch(url)
+ if (!response.ok) {
+ throw new Error('下载失败')
+ }
+ const blob = await response.blob()
+ const blobUrl = window.URL.createObjectURL(blob)
+
+ // 提取文件名
+ const filename = row.username
+
+ // 创建 a 标签并下载
+ const a = document.createElement('a')
+ a.href = blobUrl
+ a.download = filename
+ a.style.display = 'none'
+ document.body.appendChild(a)
+ a.click()
+ a.remove()
+
+ window.URL.revokeObjectURL(blobUrl)
+ } catch (err: any) {
+ ElMessage.error(`下载失败:${err.message}`)
+ }
+}
+
/** 导出按钮操作 */
const handleExport = async () => {
- const rows = selections.value;
+ const rows = selections.value
if (!rows.length) {
- message.error('请至少选择一条数据');
- return;
+ message.error('请至少选择一条数据')
+ return
}
-console.log(rows.length)
+ console.log(rows.length)
try {
// 导出的二次确认
- await message.exportConfirm();
+ await message.exportConfirm()
// 将选中的 monitorId 填入 queryParams
- queryParams.monitorId = rows.map((row: any) => row.monitorId).join(',');
+ queryParams.monitorId = rows.map((row: any) => row.monitorId).join(',')
- exportLoading.value = true;
+ exportLoading.value = true
- const data = await MonitorApi.exportMonitor(queryParams);
- download.excel(data, '监控管理.xls');
+ const data = await MonitorApi.exportMonitor(queryParams)
+ download.excel(data, '监控管理.xls')
} catch {
// 可选:错误处理
} finally {
- exportLoading.value = false;
+ exportLoading.value = false
// 导出后重置 monitorId,避免影响后续查询
- queryParams.monitorId = '';
+ queryParams.monitorId = ''
}
}
const fetchTaskList = async (taskType: string) => {
-
try {
- const res = await MonitorApi.getPaperTaskList( taskType )
+ const res = await MonitorApi.getPaperTaskList(taskType)
taskList.value = res
} catch (error) {
taskList.value = []
@@ -446,9 +455,8 @@ const handleNextStepCancel = () => {
initDialogVisible.value = false
}
-
/** 初始化 **/
onMounted(() => {
- initDialogVisible.value = true; // 显示初始弹框
+ initDialogVisible.value = true // 显示初始弹框
})
-
\ No newline at end of file
+
diff --git a/src/views/paper/question/EmailForm.vue b/src/views/paper/question/EmailForm.vue
index c186bbd..4e877c8 100644
--- a/src/views/paper/question/EmailForm.vue
+++ b/src/views/paper/question/EmailForm.vue
@@ -205,13 +205,12 @@
-->
-
+
提示:文件名称可默认不设置
@@ -273,7 +272,7 @@
-
+ -->
@@ -285,8 +284,6 @@
-
-
{
@@ -492,24 +469,6 @@ const deleteUrl = (index: number) => {
formData.value.fileUploads[index].url = ''
formData.value.fileUploads[index].fileName = ''
}
-// 媒体文件
-const mediumList = ref([] as any)
-const multipleMediumSelection = ref([] as any)
-const handleMediumSelectionChange = (val: any) => {
- multipleMediumSelection.value = val
-}
-const fileList = []
-
-const multipleDocumentSelection = ref([] as any)
-const handleDocumentSelectionChange = (val: any) => {
- multipleDocumentSelection.value = val
-}
-const handleUploadSuccess = ({ url, fileType }) => {
- const index = documentList.value.findIndex((item) => item.fileType === fileType)
- if (index !== -1) {
- documentList.value[index].url = url
- }
-}
/** 打开弹窗 */
const open = async (queryParams: any, type: string, id?: number) => {
dialogVisible.value = true
@@ -524,7 +483,6 @@ const open = async (queryParams: any, type: string, id?: number) => {
formData.value = res
console.log(formData.value)
list.value = formData.value.answerList
- documentList.value = res.fileUploads
} finally {
formLoading.value = false
}
@@ -560,7 +518,6 @@ const submitForm = async () => {
item.scoreRate = '1' // 设置默认权值为1
}
})
- formData.value.fileUploads = documentList.value
const values = Object.values(formData)
console.log(values)
// 校验表单
@@ -630,26 +587,6 @@ const resetForm = () => {
}
]
}
- documentList.value = [
- {
- quId: '',
- url: '',
- fileType: '0',
- fileName: ''
- },
- {
- quId: '',
- url: '',
- fileType: '1',
- fileName: ''
- },
- {
- quId: '',
- url: '',
- fileType: '2',
- fileName: ''
- }
- ]
list.value = []
formRef.value?.resetFields()
}
diff --git a/src/views/paper/question/WpsPptxForm.vue b/src/views/paper/question/WpsPptxForm.vue
index b1fcce0..43771a1 100644
--- a/src/views/paper/question/WpsPptxForm.vue
+++ b/src/views/paper/question/WpsPptxForm.vue
@@ -965,12 +965,12 @@ const openPoints = async () => {
}
}
/* 固定 el-dialog 高度,内容超出可滚动 */
-.fixed-dialog-height >>> .el-dialog {
+.fixed-dialog-height :deep(.el-dialog) {
height: 500px;
display: flex;
flex-direction: column;
}
-.fixed-dialog-height >>> .el-dialog__body {
+:deep(.fixed-dialog-height .el-dialog__body) {
flex: 1;
overflow: hidden;
padding: 0 20px 20px 20px;
diff --git a/src/views/paper/question/index.vue b/src/views/paper/question/index.vue
index 284e681..8e4d121 100644
--- a/src/views/paper/question/index.vue
+++ b/src/views/paper/question/index.vue
@@ -2,10 +2,10 @@
-
+
-
+