Files
en-edu/enlish-vue/src/api/plan.js
lbw fd828442b1 feat(plan): 支持学案文件下载功能
- 新增 DownLoadLessonPlanReqVO 请求类用于下载请求封装
- 在前端学案列表增加“下载”按钮,支持单条学案下载操作
- 实现前端下载接口,处理后端返回的 Blob 文件流并触发文件保存
- 后端新增下载接口,根据学案 ID 生成对应的 Word 文档并作为附件响应
- WordExportUtil 中新增按模板生成学案 Word 文档方法,支持工作日和周末模板切换
- LessonPlansService 新增根据 ID 查询学案的方法及对应 Mapper 实现
- 修改学案列表中“学案ID”标签为“计划ID”,提升表述准确性
- 下载过程中添加加载状态和错误信息提示,提升用户体验
2025-12-17 15:56:55 +08:00

70 lines
2.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import axios from "@/axios";
export function generateLessonPlan(studentId, unitId) {
return axios.post('/plan/generate', {
studentId: studentId,
unitId: unitId
})
}
export function downloadLessonPlan(data) {
return axios.post('/plan/download', data, {
// 1. 重要:必须指定响应类型为 blob否则下载的文件会损坏乱码
responseType: 'blob',
headers: {
'Content-Type': 'application/json; application/octet-stream' // 根据需要调整
}
}).then(response => {
// 2. 提取文件名 (处理后端设置的 Content-Disposition)
// 后端示例: header("Content-Disposition", "attachment; filename*=UTF-8''" + fileName)
let fileName = 'download.zip'; // 默认兜底文件名
const contentDisposition = response.headers['content-disposition'];
if (contentDisposition) {
// 正则提取 filename*=utf-8''xxx.zip 或 filename="xxx.zip"
const fileNameMatch = contentDisposition.match(/filename\*?=['"]?(?:UTF-\d['"]*)?([^;\r\n"']*)['"]?;?/);
if (fileNameMatch && fileNameMatch[1]) {
// 后端如果用了 URLEncoder这里需要 decode
fileName = decodeURIComponent(fileNameMatch[1]);
}
}
// 3. 开始下载流程
resolveBlob(response.data, fileName);
}).catch(error => {
console.error('下载失败', error);
showMessage('下载失败' + error, 'error');
// 注意:如果后端报错返回 JSON因为 responseType 是 blob
// 这里看到的 error.response.data 也是 blob需要转回文本才能看到错误信息
const reader = new FileReader();
reader.readAsText(error.response.data);
reader.onload = () => {
console.log(JSON.parse(reader.result)); // 打印后端实际报错
}
});
}
const resolveBlob = (res, fileName) => {
// 创建 Blob 对象,可以指定 type也可以让浏览器自动推断
const blob = new Blob([res], { type: 'application/octet-stream' });
// 兼容 IE/Edge (虽然现在很少用了)
if (window.navigator.msSaveOrOpenBlob) {
navigator.msSaveBlob(blob, fileName);
} else {
// 创建一个临时的 URL 指向 Blob
const link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = fileName;
// 触发点击
link.style.display = 'none';
document.body.appendChild(link);
link.click();
// 清理资源
document.body.removeChild(link);
window.URL.revokeObjectURL(link.href);
}
};