diff --git a/backend/roomroot-admin/src/main/java/com/roomroot/web/controller/jwgl/DownloadController.java b/backend/roomroot-admin/src/main/java/com/roomroot/web/controller/jwgl/DownloadController.java index b851ddd3c..1ab621dd0 100644 --- a/backend/roomroot-admin/src/main/java/com/roomroot/web/controller/jwgl/DownloadController.java +++ b/backend/roomroot-admin/src/main/java/com/roomroot/web/controller/jwgl/DownloadController.java @@ -2,6 +2,8 @@ package com.roomroot.web.controller.jwgl; import com.roomroot.common.exception.ServiceException; import com.roomroot.common.utils.file.FileUtils; +import com.roomroot.jwgl.service.TeachingMaterialService; +import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.io.IOUtils; import org.springframework.core.io.ClassPathResource; @@ -23,6 +25,9 @@ public class DownloadController { private static final String TEMPLATE_DIR = "file/"; + @Resource + private TeachingMaterialService teachingMaterialService; + /** * 人才培养方案课程数据文件模板 */ @@ -56,11 +61,11 @@ public class DownloadController { } /** - * 教材管理模板 + * 教材管理模板(动态生成,与 /teachingMaterial/template 一致) */ @GetMapping("/teaching-material") - public void downloadTeachingMaterial(HttpServletResponse response) throws IOException { - downloadTemplate(response, "教材管理.xls"); + public void downloadTeachingMaterial(HttpServletResponse response) { + teachingMaterialService.downloadTemplate(response); } /** diff --git a/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/service/impl/TeachingMaterialServiceImpl.java b/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/service/impl/TeachingMaterialServiceImpl.java index 0fe7bdf15..a3f457520 100644 --- a/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/service/impl/TeachingMaterialServiceImpl.java +++ b/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/service/impl/TeachingMaterialServiceImpl.java @@ -2,6 +2,8 @@ package com.roomroot.jwgl.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.roomroot.common.exception.ServiceException; +import com.roomroot.common.utils.file.FileUtils; import com.roomroot.jwgl.entity.JCXX; import com.roomroot.jwgl.mapper.TeachingMaterialMapper; import com.roomroot.jwgl.service.TeachingMaterialService; @@ -11,19 +13,24 @@ import com.roomroot.jwgl.utils.DateUtils; import com.roomroot.jwgl.utils.UuidUtil; import jakarta.servlet.http.HttpServletResponse; import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.DateUtil; +import org.apache.poi.ss.usermodel.Font; +import org.apache.poi.ss.usermodel.IndexedColors; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.springframework.core.io.ClassPathResource; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import jakarta.annotation.Resource; import java.io.InputStream; -import java.io.OutputStream; import java.math.BigDecimal; -import java.net.URLEncoder; import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; import java.util.List; /** @@ -43,7 +50,7 @@ public class TeachingMaterialServiceImpl implements TeachingMaterialService { jcxx.setCjsj(LocalDateTime.now()); jcxx.setXgsj(LocalDateTime.now()); String nextNum = getNextNumber(); - nextNum = getNextZeroFillCode(nextNum,4); + nextNum = getNextZeroFillCode(nextNum, 4); jcxx.setBh(nextNum); teachingMaterialMapper.insert(jcxx); } @@ -104,234 +111,205 @@ public class TeachingMaterialServiceImpl implements TeachingMaterialService { } @Override + @Transactional(rollbackFor = Exception.class) public int importExcel(MultipartFile file) { + if (file == null || file.isEmpty()) { + throw new ServiceException("导入文件不能为空"); + } + String filename = file.getOriginalFilename() == null ? "" : file.getOriginalFilename().toLowerCase(); try (InputStream is = file.getInputStream(); - Workbook workbook = file.getOriginalFilename().endsWith(".xlsx") - ? new XSSFWorkbook(is) : new HSSFWorkbook(is)) { + Workbook workbook = filename.endsWith(".xlsx") ? new XSSFWorkbook(is) : new HSSFWorkbook(is)) { - // 获取教材信息sheet Sheet sheet = workbook.getSheet("教材信息"); if (sheet == null) { sheet = workbook.getSheetAt(0); } int count = 0; - - // 在循环外获取起始编号 String nextNum = getNextNumber(); - // 从第二行开始读取数据(跳过表头) for (int i = 1; i <= sheet.getLastRowNum(); i++) { Row row = sheet.getRow(i); - if (row == null) continue; - - //获取编号 - // 跳过空行 - String bh = getCellValue(row, 0); - - JCXX jcxx = getByBh(bh); - String flag = "0"; - if(jcxx == null){ + if (row == null) { + continue; + } + String mc = nvl(getCellValue(row, 3)); + if (mc.isEmpty()) { + continue; + } + String bh = nvl(getCellValue(row, 0)); + JCXX jcxx = bh.isEmpty() ? null : getByBh(bh); + boolean insert = jcxx == null; + if (insert) { jcxx = new JCXX(); jcxx.setId(UuidUtil.getUUID()); jcxx.setDelFlag(0); jcxx.setCjsj(LocalDateTime.now()); - // 生成编号(数字字符串) - jcxx.setBh(bh == null?String.valueOf(nextNum):bh); - nextNum = getNextZeroFillCode(nextNum,4); - flag = "1"; + if (bh.isEmpty()) { + jcxx.setBh(getNextZeroFillCode(nextNum, 4)); + nextNum = jcxx.getBh(); + } else { + jcxx.setBh(bh); + } + jcxx.setSdsl(0); + jcxx.setJcsl(0); + jcxx.setKcsj(0); } jcxx.setXgsj(LocalDateTime.now()); - - // 教研室 - jcxx.setJysdh(getCellValue(row, 1)); - - // 教材代码 - jcxx.setJcdm(getCellValue(row, 2)); - - // 跳过空行 - String mc = getCellValue(row, 3); - if (mc == null || mc.isEmpty()) continue; - - // 名称 + jcxx.setJysdh(blankToNull(getCellValue(row, 1))); + jcxx.setJcdm(blankToNull(getCellValue(row, 2))); jcxx.setMc(mc); - - // ISBN - jcxx.setIsbn(getCellValue(row, 4)); - - // 出版社 - jcxx.setCbs(getCellValue(row, 5)); - - // 版次 - jcxx.setBc(getCellValue(row, 6)); - - // 开本 - jcxx.setKb(getCellValue(row, 7)); - - // 作者 - //主编 - String zb = getCellValue(row, 8) == null ? "" : getCellValue(row, 8); - //副主编 - String fzb = getCellValue(row, 9) == null ? "" : getCellValue(row, 9); - //编者 - String bz = getCellValue(row, 10)==null?"":getCellValue(row, 10); - - - jcxx.setZz(zb+" "+fzb+" "+bz); - - // 定价 - String djStr = getCellValue(row, 11); - if (djStr != null && !djStr.isEmpty()) { - try { - jcxx.setDj(new BigDecimal(djStr)); - } catch (NumberFormatException e) { - jcxx.setDj(BigDecimal.ZERO); - } + jcxx.setIsbn(blankToNull(getCellValue(row, 4))); + jcxx.setCbs(blankToNull(getCellValue(row, 5))); + jcxx.setBc(blankToNull(getCellValue(row, 6))); + jcxx.setKb(blankToNull(getCellValue(row, 7))); + jcxx.setZz(joinAuthors(getCellValue(row, 8), getCellValue(row, 9), getCellValue(row, 10))); + jcxx.setDj(parseDecimal(getCellValue(row, 11))); + jcxx.setJcfl(blankToNull(getCellValue(row, 12))); + jcxx.setJclx(blankToNull(getCellValue(row, 13))); + String jcbxlx = nvl(getCellValue(row, 14)); + if (jcbxlx.isEmpty()) { + jcbxlx = nvl(getCellValue(row, 15)); } + jcxx.setJcbxlx(blankToNull(jcbxlx)); + jcxx.setJcmj(blankToNull(getCellValue(row, 16))); + jcxx.setBxdw(blankToNull(getCellValue(row, 17))); + String teacher = nvl(getCellValue(row, 18)); + if (teacher.isEmpty()) { + teacher = nvl(getCellValue(row, 28)); + } + jcxx.setZrjyjlxff(blankToNull(teacher)); + jcxx.setJczdlx(blankToNull(getCellValue(row, 19))); + jcxx.setJccc(blankToNull(getCellValue(row, 20))); + jcxx.setJcly(blankToNull(getCellValue(row, 21))); + jcxx.setCbfs(blankToNull(getCellValue(row, 22))); + jcxx.setJldw(blankToNull(getCellValue(row, 23))); + jcxx.setCbrq(DateUtils.parseAnyDate(nvl(getCellValue(row, 24)))); + jcxx.setZblxrq(DateUtils.parseAnyDate(nvl(getCellValue(row, 25)))); + jcxx.setXqk(blankToNull(getCellValue(row, 26))); + jcxx.setBfsddw(blankToNull(getCellValue(row, 27))); + jcxx.setXcy(parseBool(getCellValue(row, 29), false)); + jcxx.setBz(blankToNull(getCellValue(row, 31))); + jcxx.setTy(parseBool(getCellValue(row, 32), false)); + fillRequiredDefaults(jcxx); - // 教材分类 - jcxx.setJcfl(getCellValue(row, 12)); - - // 教材类型 - jcxx.setJclx(getCellValue(row, 13)); - - // 教材编写类型 - jcxx.setJcbxlx(getCellValue(row, 14)); - - //教材编写类型 - jcxx.setJcbxlx(getCellValue(row, 15)==null?"":getCellValue(row, 15)); - //教材密级 - jcxx.setJcmj(getCellValue(row, 16)==null?"":getCellValue(row, 16)); - - //编写单位 - jcxx.setBxdw(getCellValue(row, 17)==null?"":getCellValue(row, 17)); - - //责任教研室 - jcxx.setZrjyjlxff(getCellValue(row, 18)==null?"":getCellValue(row, 18)); - //教材重点类型 - jcxx.setJczdlx(getCellValue(row, 19)==null?"":getCellValue(row, 19)); - //教材层次 - jcxx.setJccc(getCellValue(row, 20)==null?"":getCellValue(row, 20)); - //教材来源 - jcxx.setJcly(getCellValue(row, 21)==null?"":getCellValue(row, 21)); - //出版方式 - jcxx.setCbfs(getCellValue(row, 22)==null?"":getCellValue(row, 22)); - //计量单位 - jcxx.setJldw(getCellValue(row, 23)==null?"":getCellValue(row, 23)); - //出版日期 - String dateStr = getCellValue(row, 24)==null?"":getCellValue(row, 24); - LocalDateTime cbrq = DateUtils.parseAnyDate(dateStr); - jcxx.setCbrq(cbrq); - //自编教材立项日期 - jcxx.setJcmj(getCellValue(row, 25)==null?"":getCellValue(row, 25)); - //评选情况 - jcxx.setJcmj(getCellValue(row, 26)==null?"":getCellValue(row, 26)); - //颁发审定单位 - jcxx.setJcmj(getCellValue(row, 27)==null?"":getCellValue(row, 27)); - //责任教员及联系方式 - jcxx.setJcmj(getCellValue(row, 28)==null?"":getCellValue(row, 28)); - //需彩印 - jcxx.setJcmj(getCellValue(row, 29)==null?"":getCellValue(row, 29)); - //外协排版 - jcxx.setJcmj(getCellValue(row, 30)==null?"":getCellValue(row, 30)); - //备注 - jcxx.setJcmj(getCellValue(row, 31)==null?"":getCellValue(row, 31)); - //停用 - jcxx.setTy(false); - jcxx.setXcy(false); - - if("1".equals(flag)){ + if (insert) { teachingMaterialMapper.insert(jcxx); - }else if("0".equals(flag)){ + } else { teachingMaterialMapper.updateById(jcxx); } count++; } return count; + } catch (ServiceException e) { + throw e; } catch (Exception e) { - throw new RuntimeException("Excel解析失败: " + e.getMessage(), e); + throw new ServiceException("Excel解析失败: " + e.getMessage()); } } - @Override public void downloadTemplate(HttpServletResponse response) { - try { - // 从resources/template目录读取模板文件 - ClassPathResource resource = new ClassPathResource("file/教材管理.xls"); - InputStream is = resource.getInputStream(); + try (Workbook workbook = new XSSFWorkbook()) { + CellStyle headerStyle = workbook.createCellStyle(); + Font headerFont = workbook.createFont(); + headerFont.setBold(true); + headerStyle.setFont(headerFont); + CellStyle requiredStyle = workbook.createCellStyle(); + Font requiredFont = workbook.createFont(); + requiredFont.setBold(true); + requiredFont.setColor(IndexedColors.RED.getIndex()); + requiredStyle.setFont(requiredFont); - // 设置响应头 - response.setContentType("application/vnd.ms-excel"); - response.setHeader("Content-Disposition", "attachment;filename=" + - URLEncoder.encode("教材管理导入模板.xls", "UTF-8")); - - // 输出文件 - OutputStream os = response.getOutputStream(); - byte[] buffer = new byte[1024]; - int len; - while ((len = is.read(buffer)) != -1) { - os.write(buffer, 0, len); + String[] headers = { + "编号", "教研室代号", "教材代码", "名称*", "ISBN", "出版社", "版次", "开本", + "主编", "副主编", "编者", "定价", "教材分类", "教材类型", "教材编写类型", + "教材编写类型(备用)", "教材密级", "编写单位", "责任教员及联系方式", "教材重点类型", + "教材层次", "教材来源", "出版方式", "计量单位", "出版日期", "自编立项日期", + "评选情况", "颁发审定单位", "责任教员及联系方式(备用)", "需彩印", "外协排版(忽略)", + "备注", "停用" + }; + Sheet sheet = workbook.createSheet("教材信息"); + Row headerRow = sheet.createRow(0); + for (int i = 0; i < headers.length; i++) { + Cell cell = headerRow.createCell(i); + cell.setCellValue(headers[i]); + cell.setCellStyle(headers[i].contains("*") ? requiredStyle : headerStyle); + sheet.setColumnWidth(i, 16 * 256); } - os.flush(); - is.close(); - os.close(); + String[][] samples = { + { + "", "", "JC-DEMO-001", "高等数学(测试)", "978-7-111-00001-1", "高等教育出版社", + "第3版", "16开", "张三", "李四", "王五", "45.5", "基本教材", "院校自编", "自编", + "", "公开", "数学教研室", "张三 13800000001", "一般教材", "本科", "自购", + "公开出版", "本", "2024/08/01", "2023/12/01", "院级优秀", "教务处", "", + "否", "", "导入测试样例1", "否" + }, + { + "", "", "JC-DEMO-002", "大学物理实验(测试)", "978-7-111-00002-8", "科学出版社", + "第2版", "16开", "赵六", "", "", "32", "辅助教材", "国家规划", "选用", + "", "内部", "物理教研室", "赵六 13800000002", "规划教材", "本科", "教研保障中心外购", + "内部出版", "册", "2023/03/15", "", "", "", "", + "是", "", "导入测试样例2", "否" + }, + { + "", "", "JC-DEMO-003", "研究生英语阅读(测试)", "978-7-111-00003-5", "外语教学与研究出版社", + "第1版", "32开", "钱七", "孙八", "", "28.8", "参考资料", "军队规划", "选用", + "", "公开", "外语教研室", "钱七 13800000003", "重点教材", "研究生", "上级配发", + "公开出版", "本", "2025/01/10", "2024/06/01", "", "训练部", "", + "否", "", "导入测试样例3", "否" + } + }; + for (int r = 0; r < samples.length; r++) { + Row dataRow = sheet.createRow(r + 1); + for (int c = 0; c < samples[r].length; c++) { + dataRow.createCell(c).setCellValue(samples[r][c]); + } + } + + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + FileUtils.setAttachmentResponseHeader(response, "教材管理导入模板.xlsx"); + workbook.write(response.getOutputStream()); + response.getOutputStream().flush(); } catch (Exception e) { - throw new RuntimeException("下载模板失败: " + e.getMessage(), e); + throw new ServiceException("下载模板失败: " + e.getMessage()); } } - /** - * 获取下一个编号(四位补零) - */ private String getNextNumber() { String maxBh = teachingMaterialMapper.selectMaxBh(); - String nextNum = "0001"; if (maxBh != null && !maxBh.isEmpty()) { - try { - // 去掉前导零后解析 - nextNum = maxBh; - } catch (NumberFormatException e) { - nextNum = "0001"; - } + return maxBh; } - return nextNum; + return "0000"; } - /** - * 根据数据库最大补零编号,生成下一个编号 - * @param maxZeroCode 数据库查出的最大补零编号,为空则从00001开始 - * @param length 固定补零长度,例:5=00001 - * @return 下一个补零字符串编号 - */ public static String getNextZeroFillCode(String maxZeroCode, int length) { int num = 1; - // 数据库有编号则解析+1 if (maxZeroCode != null && maxZeroCode.trim().length() > 0) { - num = Integer.parseInt(maxZeroCode.trim()) + 1; + String digits = maxZeroCode.trim().replaceAll("\\D", ""); + if (!digits.isEmpty()) { + try { + num = Integer.parseInt(digits) + 1; + } catch (NumberFormatException ignored) { + num = 1; + } + } } - // 格式化补零 String format = "%0" + length + "d"; return String.format(format, num); } - /** - * 获取单元格字符串值 - */ private String getCellValue(Row row, int index) { Cell cell = row.getCell(index, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK); if (cell == null) { return null; } - CellType type = cell.getCellType(); - // 处理公式单元格 if (type == CellType.FORMULA) { type = cell.getCachedFormulaResultType(); } - switch (type) { case NUMERIC: - // 判断是否是日期格式 if (DateUtil.isCellDateFormatted(cell)) { java.util.Date date = cell.getDateCellValue(); if (date != null) { @@ -341,12 +319,10 @@ public class TeachingMaterialServiceImpl implements TeachingMaterialService { return null; } double num = cell.getNumericCellValue(); - // 整数就去掉小数点后多余的 .0 if (num == Math.floor(num)) { return String.valueOf((long) num); - } else { - return String.valueOf(num); } + return String.valueOf(num); case STRING: return cell.getStringCellValue().trim(); case BOOLEAN: @@ -356,25 +332,119 @@ public class TeachingMaterialServiceImpl implements TeachingMaterialService { } } - /** - * 解析日期时间字符串 - */ - private LocalDateTime parseDateTime(String dateStr) { - // 尝试多种日期格式 - String[] patterns = { - "yyyy-MM-dd HH:mm:ss", - "yyyy-MM-dd", - "yyyy/MM/dd", - "yyyy年MM月dd日" - }; - for (String pattern : patterns) { - try { - DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern); - return LocalDateTime.parse(dateStr, formatter); - } catch (Exception e) { - // 继续尝试下一个格式 - } - } - return null; + private String nvl(String value) { + return value == null ? "" : value.trim(); } -} \ No newline at end of file + + private String blankToNull(String value) { + String trimmed = nvl(value); + return trimmed.isEmpty() ? null : trimmed; + } + + private String joinAuthors(String zb, String fzb, String bz) { + StringBuilder builder = new StringBuilder(); + appendAuthor(builder, zb); + appendAuthor(builder, fzb); + appendAuthor(builder, bz); + return builder.length() == 0 ? null : builder.toString(); + } + + private void appendAuthor(StringBuilder builder, String part) { + String value = nvl(part); + if (value.isEmpty()) { + return; + } + if (builder.length() > 0) { + builder.append(' '); + } + builder.append(value); + } + + private BigDecimal parseDecimal(String text) { + String value = nvl(text); + if (value.isEmpty()) { + return null; + } + try { + return new BigDecimal(value); + } catch (NumberFormatException e) { + return BigDecimal.ZERO; + } + } + + private Boolean parseBool(String text, boolean defaultValue) { + String value = nvl(text); + if (value.isEmpty()) { + return defaultValue; + } + return "1".equals(value) || "是".equals(value) || "true".equalsIgnoreCase(value) + || "Y".equalsIgnoreCase(value); + } + + /** + * 教材信息表多列为非空且达梦空串当 NULL。导入缺列时用页面选项的第一项兜底。 + */ + private void fillRequiredDefaults(JCXX jcxx) { + if (isBlank(jcxx.getJcbxlx())) { + jcxx.setJcbxlx("自编"); + } + if (isBlank(jcxx.getZz())) { + jcxx.setZz("-"); + } + if (jcxx.getCbrq() == null) { + jcxx.setCbrq(LocalDateTime.now()); + } + if (isBlank(jcxx.getJcfl())) { + jcxx.setJcfl("基本教材"); + } + if (isBlank(jcxx.getJclx())) { + jcxx.setJclx("院校自编"); + } + if (isBlank(jcxx.getJczdlx())) { + jcxx.setJczdlx("一般教材"); + } + if (isBlank(jcxx.getJcly())) { + jcxx.setJcly("自购"); + } + if (isBlank(jcxx.getJccc())) { + jcxx.setJccc("无"); + } + if (isBlank(jcxx.getCbfs())) { + jcxx.setCbfs("内部出版"); + } + if (isBlank(jcxx.getKb())) { + jcxx.setKb("-"); + } + if (jcxx.getDj() == null) { + jcxx.setDj(BigDecimal.ZERO); + } + if (isBlank(jcxx.getJldw())) { + jcxx.setJldw("本"); + } + if (isBlank(jcxx.getJcmj())) { + jcxx.setJcmj("公开"); + } + if (jcxx.getTy() == null) { + jcxx.setTy(false); + } + if (jcxx.getXcy() == null) { + jcxx.setXcy(false); + } + if (jcxx.getSdsl() == null) { + jcxx.setSdsl(0); + } + if (jcxx.getJcsl() == null) { + jcxx.setJcsl(0); + } + if (jcxx.getKcsj() == null) { + jcxx.setKcsj(0); + } + if (jcxx.getDelFlag() == null) { + jcxx.setDelFlag(0); + } + } + + private boolean isBlank(String value) { + return value == null || value.trim().isEmpty(); + } +} diff --git a/frontend/src/api/textbook/teachingMaterial.js b/frontend/src/api/textbook/teachingMaterial.js index d65d8d590..0c94d4bf0 100644 --- a/frontend/src/api/textbook/teachingMaterial.js +++ b/frontend/src/api/textbook/teachingMaterial.js @@ -61,10 +61,10 @@ export function deleteTeachingMaterial(id) { }) } -/** 教材导入模板下载 GET /download/teaching-material */ +/** 教材导入模板下载 GET /teachingMaterial/template */ export function downloadTeachingMaterialTemplate() { return request({ - url: '/download/teaching-material', + url: '/teachingMaterial/template', method: 'get', responseType: 'blob' }) diff --git a/frontend/src/views/student/statusChange/index.vue b/frontend/src/views/student/statusChange/index.vue index 52d89ca22..7c77bdad2 100644 --- a/frontend/src/views/student/statusChange/index.vue +++ b/frontend/src/views/student/statusChange/index.vue @@ -590,7 +590,7 @@ export default { const pad = n => String(n).padStart(2, '0') const date = `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}` const time = `${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}` - return `${date} ${time}` + return `${date}T${time}` }, handleSubmit(row) { diff --git a/frontend/src/views/textbook/index.vue b/frontend/src/views/textbook/index.vue index 5a72430f8..3cf5572a7 100644 --- a/frontend/src/views/textbook/index.vue +++ b/frontend/src/views/textbook/index.vue @@ -1125,7 +1125,11 @@ export default { // ==================== 模板下载 / 导入 ==================== handleDownloadTemplate() { downloadTeachingMaterialTemplate().then(blob => { - saveAs(blob, '教材管理导入模板.xls') + if (blob && blob.type && blob.type.indexOf('json') !== -1) { + this.$message.error('模板下载失败') + return + } + saveAs(blob, '教材管理导入模板.xlsx') this.$message.success('模板下载成功') }).catch(() => {}) },