Accept Merge Request #83: (hyc -> master)

Merge Request: 【修改】生成笔试试卷按钮 加载状态

Created By: @华允传
Accepted By: @华允传
URL: https://g-iswv8783.coding.net/p/education/d/pengchen-ui-exam-vue3/git/merge/83?initial=true
This commit is contained in:
华允传
2025-05-27 16:06:09 +08:00
committed by Coding
23 changed files with 262 additions and 26 deletions

View File

@@ -69,7 +69,6 @@ export async function exportPapers(params) {
}
export async function getPaperDetailByTaskId(paperId) {
return await request.get({ url: '/exam/qu/getPaper' , params:{paperId} })
}
@@ -91,4 +90,40 @@ export async function updatePaperStatus(paperId: string, status: number) {
data: { paperId, status } // 使用data
})
}
export async function openDown(ids) {
try {
// 1. 将数组转换为逗号分隔的字符串(例如 ["id1", "id2"] → "id1,id2"
const paperIdsParam = ids.join(',');
const res = await request.download({
url: `/exam/paper/addUpload/${paperIdsParam}`,
});
// 3. 创建 Blob 并触发下载
const blob = new Blob([res]);
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
// 使用示例
const filename = `${getNowTimeString()}.zip`;
link.setAttribute('download', filename);
document.body.appendChild(link);
link.click();
link.remove();
window.URL.revokeObjectURL(url); // 释放内存
} catch (e) {
console.error('下载失败:', e);
throw new Error('下载试卷失败');
}
}
function getNowTimeString() {
const now = new Date();
const Y = now.getFullYear();
const M = String(now.getMonth() + 1).padStart(2, '0');
const D = String(now.getDate()).padStart(2, '0');
const h = String(now.getHours()).padStart(2, '0');
const m = String(now.getMinutes()).padStart(2, '0');
const s = String(now.getSeconds()).padStart(2, '0');
return `${Y}${M}${D}${h}${m}${s}`;
}

View File

@@ -192,6 +192,11 @@
</el-tab-pane> -->
<el-tab-pane v-if="formType === 'update'" name="point">
<el-alert type="warning" show-icon :closable="false">
<template #default>
<span>提示考点导入需上传考试和结果文件</span>
</template>
</el-alert>
<template #label>
<div class="custom-tabs-label">

View File

@@ -39,7 +39,7 @@
<div v-if="item.subjectName === '编程题'">
<!-- 编程题解析 -->
<div class="mt-2">
<div class="font-bold text-blue-600">解析</div>
<div class="font-bold text-blue-600">答案</div>
<pre
style="background-color: #f5f5f5; padding: 10px; border-radius: 4px; overflow-x: auto;"
>{{ item.analysis }}</pre>

View File

@@ -295,7 +295,7 @@ const fetchpaperOptions = async () => {
const res = await getPaperList(props.taskId);
PaperOptions.value = res
.filter(item => item)
.map(item => ({ label: item, value: item }));
.map(item => ({ label: item.num, value: item.paperId }));
} catch (e) {
message.error('获取题型失败:' + e.message);
}

View File

@@ -54,8 +54,18 @@
plain
@click="openSet"
>
<Icon icon="ep:plus" class="mr-5px" /> 卷调整
<Icon icon="ep:set-up" class="mr-5px" /> 卷调整
</el-button>
<el-button
type="primary"
plain
@click="openDown"
:loading="downloadLoading"
:disabled="downloadLoading"
>
<Icon icon="ep:files" class="mr-5px" />
生成笔试试卷
</el-button>
<!-- 批量删除按钮 -->
<!-- <el-button
type="danger"
@@ -70,7 +80,7 @@
<!-- 列表展示 -->
<ContentWrap>
<el-table v-loading="loading" :data="list" :row-key="row => row.id" ref="tableRef" :selected-rows="selectedRows">
<el-table v-loading="loading" :data="list" :row-key="row => row.id" ref="tableRef" @selection-change="handleSelectionChange">
<!-- 多选列 -->
<el-table-column type="selection" width="55" />
@@ -252,7 +262,9 @@ const reload = () => {
getList();
};
const handleSelectionChange = (rows) => {
selections.value = rows;
}
// 搜索操作
const handleQuery = () => {
queryParams.pageNo = 1;
@@ -279,7 +291,33 @@ const openSet = () => {
taskSetRef.value?.open();
});
};
/** 表格选中数据 */
const selections = ref([]);
const downloadLoading = ref(false)
const openDown = async () => {
try {
const rows = selections.value;
if (!rows.length) {
message.error('请至少选择一条数据');
return;
}
downloadLoading.value = true;
message.info('正在生成试卷中,请稍后...');
selectedRows.value = rows.map((d: any) => d.paperId);
await PaperApi.openDown(selectedRows.value);
message.success(t('下载成功'));
await getList();
} catch (error) {
console.error(error);
message.error('下载失败');
} finally {
downloadLoading.value = false;
}
};
// 打开编辑弹窗
const openEdit = (type: string, row?: object) => {
showEdit.value = true;

View File

@@ -39,7 +39,7 @@
<div v-if="item.subjectName === '编程题'">
<!-- 编程题解析 -->
<div class="mt-2">
<div class="font-bold text-blue-600">解析</div>
<div class="font-bold text-blue-600">答案</div>
<pre
style="background-color: #f5f5f5; padding: 10px; border-radius: 4px; overflow-x: auto;"
>{{ item.analysis }}</pre>

View File

@@ -295,7 +295,7 @@ const fetchpaperOptions = async () => {
const res = await getPaperList(props.taskId);
PaperOptions.value = res
.filter(item => item)
.map(item => ({ label: item, value: item }));
.map(item => ({ label: item.num, value: item.paperId }));
} catch (e) {
message.error('获取题型失败:' + e.message);
}

View File

@@ -54,7 +54,7 @@
plain
@click="openSet"
>
<Icon icon="ep:plus" class="mr-5px" /> 卷调整
<Icon icon="ep:plus" class="mr-5px" /> 卷调整
</el-button>
<!-- 批量删除按钮 -->
<!-- <el-button

View File

@@ -39,7 +39,7 @@
<div v-if="item.subjectName === '编程题'">
<!-- 编程题解析 -->
<div class="mt-2">
<div class="font-bold text-blue-600">解析</div>
<div class="font-bold text-blue-600">答案</div>
<pre
style="background-color: #f5f5f5; padding: 10px; border-radius: 4px; overflow-x: auto;"
>{{ item.analysis }}</pre>

View File

@@ -295,7 +295,7 @@ const fetchpaperOptions = async () => {
const res = await getPaperList(props.taskId);
PaperOptions.value = res
.filter(item => item)
.map(item => ({ label: item, value: item }));
.map(item => ({ label: item.num, value: item.paperId }));
} catch (e) {
message.error('获取题型失败:' + e.message);
}

View File

@@ -54,7 +54,14 @@
plain
@click="openSet"
>
<Icon icon="ep:plus" class="mr-5px" /> 卷调整
<Icon icon="ep:set-up" class="mr-5px" /> 卷调整
</el-button>
<el-button
type="primary"
plain
@click="openDown"
>
<Icon icon="ep:files" class="mr-5px" /> 生成笔试试卷
</el-button>
<!-- 批量删除按钮 -->
<!-- <el-button
@@ -279,7 +286,24 @@ const openSet = () => {
taskSetRef.value?.open();
});
};
/** 表格选中数据 */
const selections = ref([]);
const openDown = async () => {
try {
const rows = selections.value;
if (!rows.length) {
message.error('请至少选择一条数据');
return;
}
selectedRows.value = rows.map((d: any) => d.paperId); // 保存选中的行数据
await PaperApi.openDown(selectedRows.value)
message.success(t('common.delSuccess'))
// 刷新列表
await getList()
} catch {}
};
// 打开编辑弹窗
const openEdit = (type: string, row?: object) => {
showEdit.value = true;

View File

@@ -39,7 +39,7 @@
<div v-if="item.subjectName === '编程题'">
<!-- 编程题解析 -->
<div class="mt-2">
<div class="font-bold text-blue-600">解析</div>
<div class="font-bold text-blue-600">答案</div>
<pre
style="background-color: #f5f5f5; padding: 10px; border-radius: 4px; overflow-x: auto;"
>{{ item.analysis }}</pre>

View File

@@ -295,7 +295,7 @@ const fetchpaperOptions = async () => {
const res = await getPaperList(props.taskId);
PaperOptions.value = res
.filter(item => item)
.map(item => ({ label: item, value: item }));
.map(item => ({ label: item.num, value: item.paperId }));
} catch (e) {
message.error('获取题型失败:' + e.message);
}

View File

@@ -54,7 +54,14 @@
plain
@click="openSet"
>
<Icon icon="ep:plus" class="mr-5px" /> 卷调整
<Icon icon="ep:set-up" class="mr-5px" /> 卷调整
</el-button>
<el-button
type="primary"
plain
@click="openDown"
>
<Icon icon="ep:files" class="mr-5px" /> 生成笔试试卷
</el-button>
<!-- 批量删除按钮 -->
<!-- <el-button
@@ -279,7 +286,24 @@ const openSet = () => {
taskSetRef.value?.open();
});
};
/** 表格选中数据 */
const selections = ref([]);
const openDown = async () => {
try {
const rows = selections.value;
if (!rows.length) {
message.error('请至少选择一条数据');
return;
}
selectedRows.value = rows.map((d: any) => d.paperId); // 保存选中的行数据
await PaperApi.openDown(selectedRows.value)
message.success(t('common.delSuccess'))
// 刷新列表
await getList()
} catch {}
};
// 打开编辑弹窗
const openEdit = (type: string, row?: object) => {
showEdit.value = true;

View File

@@ -39,7 +39,7 @@
<div v-if="item.subjectName === '编程题'">
<!-- 编程题解析 -->
<div class="mt-2">
<div class="font-bold text-blue-600">解析</div>
<div class="font-bold text-blue-600">答案</div>
<pre
style="background-color: #f5f5f5; padding: 10px; border-radius: 4px; overflow-x: auto;"
>{{ item.analysis }}</pre>

View File

@@ -295,7 +295,7 @@ const fetchpaperOptions = async () => {
const res = await getPaperList(props.taskId);
PaperOptions.value = res
.filter(item => item)
.map(item => ({ label: item, value: item }));
.map(item => ({ label: item.num, value: item.paperId }));
} catch (e) {
message.error('获取题型失败:' + e.message);
}

View File

@@ -54,7 +54,14 @@
plain
@click="openSet"
>
<Icon icon="ep:plus" class="mr-5px" /> 卷调整
<Icon icon="ep:set-up" class="mr-5px" /> 卷调整
</el-button>
<el-button
type="primary"
plain
@click="openDown"
>
<Icon icon="ep:files" class="mr-5px" /> 生成笔试试卷
</el-button>
<!-- 批量删除按钮 -->
<!-- <el-button
@@ -279,7 +286,24 @@ const openSet = () => {
taskSetRef.value?.open();
});
};
/** 表格选中数据 */
const selections = ref([]);
const openDown = async () => {
try {
const rows = selections.value;
if (!rows.length) {
message.error('请至少选择一条数据');
return;
}
selectedRows.value = rows.map((d: any) => d.paperId); // 保存选中的行数据
await PaperApi.openDown(selectedRows.value)
message.success(t('common.delSuccess'))
// 刷新列表
await getList()
} catch {}
};
// 打开编辑弹窗
const openEdit = (type: string, row?: object) => {
showEdit.value = true;

View File

@@ -39,7 +39,7 @@
<div v-if="item.subjectName === '编程题'">
<!-- 编程题解析 -->
<div class="mt-2">
<div class="font-bold text-blue-600">解析</div>
<div class="font-bold text-blue-600">答案</div>
<pre
style="background-color: #f5f5f5; padding: 10px; border-radius: 4px; overflow-x: auto;"
>{{ item.analysis }}</pre>

View File

@@ -295,7 +295,7 @@ const fetchpaperOptions = async () => {
const res = await getPaperList(props.taskId);
PaperOptions.value = res
.filter(item => item)
.map(item => ({ label: item, value: item }));
.map(item => ({ label: item.num, value: item.paperId }));
} catch (e) {
message.error('获取题型失败:' + e.message);
}

View File

@@ -54,8 +54,18 @@
plain
@click="openSet"
>
<Icon icon="ep:plus" class="mr-5px" /> 卷调整
<Icon icon="ep:set-up" class="mr-5px" /> 卷调整
</el-button>
<el-button
type="primary"
plain
@click="openDown"
:loading="downloadLoading"
:disabled="downloadLoading"
>
<Icon icon="ep:files" class="mr-5px" />
生成笔试试卷
</el-button>
<!-- 批量删除按钮 -->
<!-- <el-button
type="danger"
@@ -70,7 +80,7 @@
<!-- 列表展示 -->
<ContentWrap>
<el-table v-loading="loading" :data="list" :row-key="row => row.id" ref="tableRef" :selected-rows="selectedRows">
<el-table v-loading="loading" :data="list" :row-key="row => row.id" ref="tableRef" @selection-change="handleSelectionChange">
<!-- 多选列 -->
<el-table-column type="selection" width="55" />
@@ -253,6 +263,9 @@ const reload = () => {
};
const handleSelectionChange = (rows) => {
selections.value = rows;
}
// 搜索操作
const handleQuery = () => {
queryParams.pageNo = 1;
@@ -279,7 +292,33 @@ const openSet = () => {
taskSetRef.value?.open();
});
};
/** 表格选中数据 */
const selections = ref([]);
const downloadLoading = ref(false)
const openDown = async () => {
try {
const rows = selections.value;
if (!rows.length) {
message.error('请至少选择一条数据');
return;
}
downloadLoading.value = true;
message.info('正在生成试卷中,请稍后...');
selectedRows.value = rows.map((d: any) => d.paperId);
await PaperApi.openDown(selectedRows.value);
message.success(t('下载成功'));
await getList();
} catch (error) {
console.error(error);
message.error('下载失败');
} finally {
downloadLoading.value = false;
}
};
// 打开编辑弹窗
const openEdit = (type: string, row?: object) => {
showEdit.value = true;

View File

@@ -39,7 +39,7 @@
<div v-if="item.subjectName === '编程题'">
<!-- 编程题解析 -->
<div class="mt-2">
<div class="font-bold text-blue-600">解析</div>
<div class="font-bold text-blue-600">答案</div>
<pre
style="background-color: #f5f5f5; padding: 10px; border-radius: 4px; overflow-x: auto;"
>{{ item.analysis }}</pre>

View File

@@ -295,7 +295,7 @@ const fetchpaperOptions = async () => {
const res = await getPaperList(props.taskId);
PaperOptions.value = res
.filter(item => item)
.map(item => ({ label: item, value: item }));
.map(item => ({ label: item.num, value: item.paperId }));
} catch (e) {
message.error('获取题型失败:' + e.message);
}

View File

@@ -54,8 +54,19 @@
plain
@click="openSet"
>
<Icon icon="ep:plus" class="mr-5px" /> 卷调整
<Icon icon="ep:set-up" class="mr-5px" /> 卷调整
</el-button>
<el-button
type="primary"
plain
@click="openDown"
:loading="downloadLoading"
:disabled="downloadLoading"
>
<Icon icon="ep:files" class="mr-5px" />
生成笔试试卷
</el-button>
<!-- 批量删除按钮 -->
<!-- <el-button
type="danger"
@@ -70,7 +81,7 @@
<!-- 列表展示 -->
<ContentWrap>
<el-table v-loading="loading" :data="list" :row-key="row => row.id" ref="tableRef" :selected-rows="selectedRows">
<el-table v-loading="loading" :data="list" :row-key="row => row.id" ref="tableRef" @selection-change="handleSelectionChange">
<!-- 多选列 -->
<el-table-column type="selection" width="55" />
@@ -280,6 +291,42 @@ const openSet = () => {
});
};
/** 表格选中数据 */
const selections = ref([]);
const downloadLoading = ref(false)
const openDown = async () => {
try {
const rows = selections.value;
if (!rows.length) {
message.error('请至少选择一条数据');
return;
}
downloadLoading.value = true;
message.info('正在生成试卷中,请稍后...');
selectedRows.value = rows.map((d: any) => d.paperId);
await PaperApi.openDown(selectedRows.value);
message.success(t('下载成功'));
await getList();
} catch (error) {
console.error(error);
message.error('下载失败');
} finally {
downloadLoading.value = false;
}
};
const handleSelectionChange = (rows) => {
selections.value = rows;
}
// 打开编辑弹窗
const openEdit = (type: string, row?: object) => {
showEdit.value = true;