From f2a53a6e33fa2d98293ba3e7b12784d51395af3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E8=90=8C=E6=96=B0?= <13658798+jjhyyds@user.noreply.gitee.com> Date: Mon, 12 Aug 2024 16:58:26 +0800 Subject: [PATCH] 8.12 --- .../backend/model/dto/chapter/ChapterDTO.java | 1 - .../model/dto/chapter/ChapterExcelDTO.java | 100 ++++++++++++ .../entity/chapter/TemporaryChapter.java | 2 +- .../service/chapter/IChapterService.java | 4 +- .../impl/chapter/ChapterServiceImpl.java | 13 +- .../backend/utils/Chapter/ExcelParser.java | 24 ++- .../backend/utils/Chapter/SheetHandler.java | 145 ++++++++++-------- .../utils/Chapter/SheetPreScanner.java | 34 ++++ 8 files changed, 248 insertions(+), 75 deletions(-) create mode 100644 src/main/java/com/teaching/backend/model/dto/chapter/ChapterExcelDTO.java create mode 100644 src/main/java/com/teaching/backend/utils/Chapter/SheetPreScanner.java diff --git a/src/main/java/com/teaching/backend/model/dto/chapter/ChapterDTO.java b/src/main/java/com/teaching/backend/model/dto/chapter/ChapterDTO.java index ab71af7..da34698 100644 --- a/src/main/java/com/teaching/backend/model/dto/chapter/ChapterDTO.java +++ b/src/main/java/com/teaching/backend/model/dto/chapter/ChapterDTO.java @@ -67,7 +67,6 @@ public class ChapterDTO implements Serializable { @ApiModelProperty(value = "要求") private String requirement; - @ApiModelProperty(value = "线上学时") private String onlineClassHours; diff --git a/src/main/java/com/teaching/backend/model/dto/chapter/ChapterExcelDTO.java b/src/main/java/com/teaching/backend/model/dto/chapter/ChapterExcelDTO.java new file mode 100644 index 0000000..f74249b --- /dev/null +++ b/src/main/java/com/teaching/backend/model/dto/chapter/ChapterExcelDTO.java @@ -0,0 +1,100 @@ +package com.teaching.backend.model.dto.chapter; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * ClassName: ChapterExcelDto + * Package: com.teaching.backend.model.dto.chapter + * Description: + * + * @Author 姜钧瀚 + * @Create 2024/8/10 13:44 + * @Version 1.0 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ChapterExcelDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "创建人") + private String createBy; + + + @ApiModelProperty(value = "创建日期") + @JsonFormat(pattern = "yyyy/M/d HH:mm:ss") + private LocalDateTime createTime; + + @ApiModelProperty(value = "更新人") + private String updateBy; + + @ApiModelProperty(value = "更新日期") + @JsonFormat(pattern = "yyyy/M/d HH-mm-ss") + private LocalDateTime updateTime; + + @ApiModelProperty(value = "所属部门") + private String sysOrgCode; + + @ApiModelProperty(value = "序号") + private Double orderNum; + + @ApiModelProperty(value = "章节名称") + private String name; + + @ApiModelProperty(value = "简介") + private String content; + + @ApiModelProperty(value = "父章节") + private Long pid; + + @ApiModelProperty(value = "课程id") + private String courseId; + + @ApiModelProperty(value = "课程目标") + private String courseObjectivesId; + + @ApiModelProperty(value = "总学时") + private double totalClassHours; + + @ApiModelProperty(value = "要求") + private String requirement; + + @TableField(exist = false) + @ApiModelProperty(value = "是否是节") + private boolean isSection; + + + @TableField(exist = false) + @ApiModelProperty(value = "章内序号") + private Integer internalOrder; + + @ApiModelProperty(value = "线上学时") + private String onlineClassHours; + + @ApiModelProperty(value = "周次") + private String zc; + + + @ApiModelProperty(value = "内部序号显示") + private String numshow; + + @ApiModelProperty(value = "excel上级序号") + @TableField(exist = false) + private Long ParentExcelId; + + @ApiModelProperty(value = "excel序号") + @TableField(exist = false) + private Long ExcelId; + + public void setIsSection(boolean b) { + this.isSection=b; + } +} \ No newline at end of file diff --git a/src/main/java/com/teaching/backend/model/entity/chapter/TemporaryChapter.java b/src/main/java/com/teaching/backend/model/entity/chapter/TemporaryChapter.java index d7f371b..756471b 100644 --- a/src/main/java/com/teaching/backend/model/entity/chapter/TemporaryChapter.java +++ b/src/main/java/com/teaching/backend/model/entity/chapter/TemporaryChapter.java @@ -69,7 +69,7 @@ public class TemporaryChapter implements Serializable { private String courseObjectivesId; @ApiModelProperty(value = "总学时") - private String totalClassHours; + private double totalClassHours; @ApiModelProperty(value = "要求") private String requirement; diff --git a/src/main/java/com/teaching/backend/service/chapter/IChapterService.java b/src/main/java/com/teaching/backend/service/chapter/IChapterService.java index 6eafd1f..875a4aa 100644 --- a/src/main/java/com/teaching/backend/service/chapter/IChapterService.java +++ b/src/main/java/com/teaching/backend/service/chapter/IChapterService.java @@ -4,12 +4,12 @@ package com.teaching.backend.service.chapter; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import com.teaching.backend.model.dto.chapter.ChapterDTO; +import com.teaching.backend.model.dto.chapter.ChapterExcelDTO; import com.teaching.backend.model.entity.chapter.Chapter; import com.teaching.backend.model.vo.chapter.ChapterVo; import javax.servlet.http.HttpServletResponse; import java.io.IOException; -import java.io.UnsupportedEncodingException; import java.util.LinkedList; import java.util.List; @@ -54,7 +54,7 @@ public interface IChapterService extends IService { void moveDataFromTemporaryToFinal(); - Long saveToTemporaryTable(ChapterDTO chapterDTO); + Long saveToTemporaryTable(ChapterExcelDTO chapterDTO); void downExcel(HttpServletResponse response) throws IOException; diff --git a/src/main/java/com/teaching/backend/service/impl/chapter/ChapterServiceImpl.java b/src/main/java/com/teaching/backend/service/impl/chapter/ChapterServiceImpl.java index 109c5ee..d330a6d 100644 --- a/src/main/java/com/teaching/backend/service/impl/chapter/ChapterServiceImpl.java +++ b/src/main/java/com/teaching/backend/service/impl/chapter/ChapterServiceImpl.java @@ -14,12 +14,12 @@ import com.teaching.backend.mapper.chapter.ChapterMapper; import com.teaching.backend.mapper.chapter.TemporaryChapterMapper; import com.teaching.backend.model.dto.chapter.ChapterDTO; +import com.teaching.backend.model.dto.chapter.ChapterExcelDTO; import com.teaching.backend.model.entity.chapter.Chapter; import com.teaching.backend.model.entity.chapter.TemporaryChapter; import com.teaching.backend.model.entity.knowtmp.Knowtmp; import com.teaching.backend.model.vo.chapter.ChapterVo; -import com.teaching.backend.service.Know.KnowService; import com.teaching.backend.service.chapter.IChapterService; import com.teaching.backend.utils.Chapter.ExcelUtils; import org.springframework.beans.BeanUtils; @@ -29,7 +29,6 @@ import org.springframework.transaction.annotation.Transactional; import javax.servlet.http.HttpServletResponse; import java.io.IOException; -import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; @@ -517,7 +516,7 @@ public class ChapterServiceImpl extends ServiceImpl impl @Transactional(rollbackFor = Exception.class) @Override - public Long saveToTemporaryTable(ChapterDTO chapterDTO) { + public Long saveToTemporaryTable(ChapterExcelDTO chapterDTO) { TemporaryChapter temporaryChapter = new TemporaryChapter(); try { BeanUtils.copyProperties(chapterDTO, temporaryChapter); @@ -526,10 +525,13 @@ public class ChapterServiceImpl extends ServiceImpl impl } Long pid = temporaryChapter.getPid(); + //pid=0的时候 if (pid == null || pid == 0) { temporaryChapter.setPid(0L); setChapterOrder(temporaryChapter, 0L); - } else { + } + //pid!=0的时候 + else { TemporaryChapter parentChapter = temporaryChapterMapper.selectById(pid); if (parentChapter != null) { temporaryChapter.setPid(parentChapter.getId()); @@ -538,8 +540,9 @@ public class ChapterServiceImpl extends ServiceImpl impl throw new BusinessException(ErrorCode.PARAMS_ERROR, "未找到父章节,ID 为: " + pid); } } - +// 执行 temporaryChapterMapper.insert(temporaryChapter); + return temporaryChapter.getId(); } diff --git a/src/main/java/com/teaching/backend/utils/Chapter/ExcelParser.java b/src/main/java/com/teaching/backend/utils/Chapter/ExcelParser.java index 04da20d..612e073 100644 --- a/src/main/java/com/teaching/backend/utils/Chapter/ExcelParser.java +++ b/src/main/java/com/teaching/backend/utils/Chapter/ExcelParser.java @@ -13,10 +13,13 @@ package com.teaching.backend.utils.Chapter; import com.teaching.backend.mapper.chapter.TemporaryChapterMapper; import com.teaching.backend.service.chapter.IChapterService; import org.apache.poi.openxml4j.opc.OPCPackage; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.eventusermodel.XSSFReader; import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler; import org.apache.poi.xssf.model.SharedStringsTable; import org.apache.poi.xssf.model.StylesTable; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.xml.sax.InputSource; @@ -40,20 +43,35 @@ public class ExcelParser { public List parse(InputStream inputStream, String courseId) throws Exception { OPCPackage pkg = OPCPackage.open(inputStream); List validationErrors = new ArrayList<>(); + int totalRows = 0; try { XSSFReader reader = new XSSFReader(pkg); SharedStringsTable sst = reader.getSharedStringsTable(); StylesTable styles = reader.getStylesTable(); XMLReader parser = XMLReaderFactory.createXMLReader(); - SheetHandler sheetHandler = new SheetHandler(temporaryChapterMapper, chapterService, courseId); - parser.setContentHandler(new XSSFSheetXMLHandler(styles, sst, sheetHandler, false)); - XSSFReader.SheetIterator sheets = (XSSFReader.SheetIterator) reader.getSheetsData(); + SheetPreScanner preScanner = new SheetPreScanner(); + while (sheets.hasNext()) { + InputStream sheetstream = sheets.next(); + InputSource sheetSource = new InputSource(sheetstream); + try { + parser.setContentHandler(new XSSFSheetXMLHandler(styles, sst, preScanner, false)); + parser.parse(sheetSource); + } finally { + sheetstream.close(); + } + } + totalRows = preScanner.getRowCount(); + + sheets = (XSSFReader.SheetIterator) reader.getSheetsData(); + SheetHandler sheetHandler = null; while (sheets.hasNext()) { InputStream sheetstream = sheets.next(); InputSource sheetSource = new InputSource(sheetstream); try { + sheetHandler = new SheetHandler(temporaryChapterMapper, chapterService, courseId, totalRows); + parser.setContentHandler(new XSSFSheetXMLHandler(styles, sst, sheetHandler, false)); parser.parse(sheetSource); } finally { sheetstream.close(); diff --git a/src/main/java/com/teaching/backend/utils/Chapter/SheetHandler.java b/src/main/java/com/teaching/backend/utils/Chapter/SheetHandler.java index 23f80d6..d791fa6 100644 --- a/src/main/java/com/teaching/backend/utils/Chapter/SheetHandler.java +++ b/src/main/java/com/teaching/backend/utils/Chapter/SheetHandler.java @@ -3,10 +3,17 @@ package com.teaching.backend.utils.Chapter; import com.teaching.backend.common.ErrorCode; import com.teaching.backend.exception.BusinessException; import com.teaching.backend.mapper.chapter.TemporaryChapterMapper; -import com.teaching.backend.model.dto.chapter.ChapterDTO; +import com.teaching.backend.model.dto.chapter.ChapterExcelDTO; import com.teaching.backend.service.chapter.IChapterService; + +import jdk.nashorn.internal.ir.IfNode; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.ss.util.CellReference; import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler; + import org.apache.poi.xssf.usermodel.XSSFComment; + +import org.apache.poi.xssf.usermodel.XSSFSheet; import org.springframework.transaction.annotation.Transactional; import java.util.*; @@ -23,127 +30,139 @@ import java.util.*; public class SheetHandler implements XSSFSheetXMLHandler.SheetContentsHandler { - - private final TemporaryChapterMapper temporaryChapterMapper; - + private Long currentChapterPid; + private final TemporaryChapterMapper temporaryChapterMapper; + private Double chapterHour; private final IChapterService chapterService; private final String courseId; - private ChapterDTO chapterDTO; + private ChapterExcelDTO chapterDTO; private Map excelIdToDatabaseIdMap = new HashMap<>(); private List validationErrors = new ArrayList<>(); private boolean hasErrors = false; - private List collectedChapters = new ArrayList<>(); + private int totalRows; - public SheetHandler(TemporaryChapterMapper temporaryChapterMapper, IChapterService chapterService, String courseId) { + + + public SheetHandler(TemporaryChapterMapper temporaryChapterMapper, IChapterService chapterService, String courseId,int totalRows) { this.temporaryChapterMapper = temporaryChapterMapper; this.chapterService = chapterService; this.courseId = courseId; + this.totalRows=totalRows; } @Override public void startRow(int rowIndex) { - if (rowIndex == 0) { - chapterDTO = null; + if (rowIndex < totalRows - 1) { + if (rowIndex == 0 || rowIndex == 1) { + chapterDTO = null; + } else { + chapterDTO = new ChapterExcelDTO(); + chapterDTO.setCourseId(courseId); + } } else { - chapterDTO = new ChapterDTO(); - chapterDTO.setCourseId(courseId); + chapterDTO = null; } - } - @Override - public void endRow(int rowIndex) { - if (rowIndex != 0 && chapterDTO != null) { - List errors = validateChapter(chapterDTO); - if (!errors.isEmpty()) { - validationErrors.addAll(errors); - hasErrors = true; - return; - } - - collectedChapters.add(chapterDTO); - } } - @Transactional(rollbackFor = Exception.class) + @Transactional(rollbackFor = Exception.class) public List finalizeProcess() { if (hasErrors) { return validationErrors; } - for (ChapterDTO chapter : collectedChapters) { - if (chapter.getParentExcelId() == null || chapter.getParentExcelId() == 0) { - saveToTemporaryTable(chapter); - } - } - - - for (ChapterDTO chapter : collectedChapters) { - if (chapter.getParentExcelId() != null && chapter.getParentExcelId() != 0) { - saveToTemporaryTable(chapter); - } - } - - chapterService.moveDataFromTemporaryToFinal(); return Collections.emptyList(); } - - private void saveToTemporaryTable(ChapterDTO chapterDTO) { + private void saveToTemporaryTable(ChapterExcelDTO chapterDTO) { Long pid = chapterDTO.getParentExcelId(); if (pid != null && pid != 0) { - Long parentId = excelIdToDatabaseIdMap.get(pid); if (parentId != null) { chapterDTO.setPid(parentId); } else { - temporaryChapterMapper.deleteAll(); throw new BusinessException(ErrorCode.PARAMS_ERROR, "未找到父章节,Excel ID 为: " + pid); - } } - - Long savedChapterId = chapterService.saveToTemporaryTable(chapterDTO); excelIdToDatabaseIdMap.put(chapterDTO.getExcelId(), savedChapterId); - } + } + private List validateChapter(ChapterExcelDTO chapterDTO) { + List errors = new ArrayList<>(); + return errors; + } + @Override + public void endRow(int rowIndex) { + if (rowIndex != 0 && chapterDTO != null) { + List errors = validateChapter(chapterDTO); + if (!errors.isEmpty()) { + validationErrors.addAll(errors); + hasErrors = true; + return; + } - private List validateChapter(ChapterDTO chapterDTO) { - List errors = new ArrayList<>(); - if (chapterDTO.getName() == null || chapterDTO.getName().isEmpty()) { - errors.add("编号:"+chapterDTO.getExcelId()+"的章节名字不能为空"); + if (chapterDTO.isSection()) { + if (currentChapterPid != null) { + chapterDTO.setTotalClassHours(chapterHour); + chapterDTO.setPid(currentChapterPid); + saveToTemporaryTable(chapterDTO); + } else { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "未找到父章节,Excel ID 为: " + chapterDTO.getExcelId()); + } + } } - if (chapterDTO.getExcelId() == null || chapterDTO.getExcelId() <= 0) { - errors.add("编号不能小于0"); - } - if (chapterDTO.getParentExcelId() == null || chapterDTO.getParentExcelId() < 0) { - errors.add("编号:"+chapterDTO.getExcelId()+"的上级编号不能小于0"); - } - if (chapterDTO.getParentExcelId().equals(chapterDTO.getExcelId())) { - errors.add("编号:"+chapterDTO.getExcelId()+"的 上级编号不能等于其自身"); - } - return errors; } @Override public void cell(String cellReference, String formattedValue, XSSFComment comment) { - if (chapterDTO != null && formattedValue != null) { + if (chapterDTO != null) { String letter = cellReference.substring(0, 1); + switch (letter) { case "A": chapterDTO.setExcelId(Long.valueOf(formattedValue)); break; + case "B": chapterDTO.setName(formattedValue); break; + case "C": - chapterDTO.setParentExcelId(Long.valueOf(formattedValue)); + if (!chapterDTO.isSection()) { + chapterDTO.setTotalClassHours(Double.parseDouble(formattedValue)); + saveToTemporaryTable(chapterDTO); + currentChapterPid = excelIdToDatabaseIdMap.get(chapterDTO.getExcelId()); + } + break; + + case "D": + chapterDTO.setOrderNum(Double.valueOf(formattedValue)); break; + + case "E": + if (!formattedValue.isEmpty()) { + chapterDTO.setName(formattedValue); + chapterDTO.setIsSection(true); + } + break; + + case "F": + if (chapterDTO.isSection()) { + chapterDTO.setTotalClassHours(Double.parseDouble(formattedValue)); + chapterHour = chapterDTO.getTotalClassHours(); + } + break; + } + } + + } + } \ No newline at end of file diff --git a/src/main/java/com/teaching/backend/utils/Chapter/SheetPreScanner.java b/src/main/java/com/teaching/backend/utils/Chapter/SheetPreScanner.java new file mode 100644 index 0000000..95caa75 --- /dev/null +++ b/src/main/java/com/teaching/backend/utils/Chapter/SheetPreScanner.java @@ -0,0 +1,34 @@ +package com.teaching.backend.utils.Chapter; + +import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler; +import org.apache.poi.xssf.usermodel.XSSFComment; + +/** + * ClassName: Sheet + * Package: com.teaching.backend.utils.Chapter + * Description: + * + * @Author 姜钧瀚 + * @Create 2024/8/11 18:04 + * @Version 1.0 + */ +public class SheetPreScanner implements XSSFSheetXMLHandler.SheetContentsHandler { + private int rowCount = 0; + + @Override + public void startRow(int rowNum) { + rowCount++; + } + + @Override + public void endRow(int rowNum) { + } + + @Override + public void cell(String cellReference, String formattedValue, XSSFComment comment) { + } + + public int getRowCount() { + return rowCount; + } +}