|
@@ -1,43 +1,52 @@
|
|
|
package com.xjrsoft.module.base.service.impl;
|
|
|
|
|
|
+import com.alibaba.excel.EasyExcel;
|
|
|
+import com.alibaba.excel.support.ExcelTypeEnum;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
import com.github.yulichang.base.MPJBaseServiceImpl;
|
|
|
import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
|
|
import com.xjrsoft.common.enums.ArchivesStatusEnum;
|
|
|
+import com.xjrsoft.common.enums.DeleteMark;
|
|
|
+import com.xjrsoft.common.enums.UseSemesterTypeEnum;
|
|
|
import com.xjrsoft.common.exception.MyException;
|
|
|
import com.xjrsoft.common.utils.VoToColumnUtil;
|
|
|
import com.xjrsoft.module.base.dto.BaseClassCoursePageDto;
|
|
|
import com.xjrsoft.module.base.dto.ClassCourseReuseDto;
|
|
|
-import com.xjrsoft.module.base.entity.BaseClassCourse;
|
|
|
-import com.xjrsoft.module.base.entity.BaseCourseSubject;
|
|
|
-import com.xjrsoft.module.base.entity.ClassCourseTextbook;
|
|
|
-import com.xjrsoft.module.base.entity.CourseBookInfo;
|
|
|
+import com.xjrsoft.module.base.entity.*;
|
|
|
import com.xjrsoft.module.base.mapper.BaseClassCourseMapper;
|
|
|
+import com.xjrsoft.module.base.mapper.BaseClassMapper;
|
|
|
import com.xjrsoft.module.base.service.IBaseClassCourseService;
|
|
|
+import com.xjrsoft.module.base.vo.BaseClassCourseExportListVo;
|
|
|
import com.xjrsoft.module.base.vo.BaseClassCoursePageVo;
|
|
|
+import com.xjrsoft.module.generator.entity.ImportConfig;
|
|
|
+import com.xjrsoft.module.organization.entity.Department;
|
|
|
import com.xjrsoft.module.student.entity.BaseStudentSchoolRoll;
|
|
|
import com.xjrsoft.module.student.mapper.BaseStudentSchoolRollMapper;
|
|
|
+import com.xjrsoft.module.base.dto.ClassCourseTextbookExportQueryDto;
|
|
|
+import com.xjrsoft.module.base.vo.ClassCourseTextbookExportQueryVo;
|
|
|
import com.xjrsoft.module.system.entity.DictionaryDetail;
|
|
|
-import com.xjrsoft.module.textbook.dto.TextbookSubscriptionExportQueryListDto;
|
|
|
import com.xjrsoft.module.textbook.entity.Textbook;
|
|
|
import com.xjrsoft.module.textbook.entity.TextbookStudentClaim;
|
|
|
-import com.xjrsoft.module.textbook.entity.TextbookSubscription;
|
|
|
-import com.xjrsoft.module.textbook.entity.WfTextbookSubscriptionItem;
|
|
|
import com.xjrsoft.module.textbook.mapper.TextbookStudentClaimMapper;
|
|
|
-import com.xjrsoft.module.textbook.vo.TextbookSubscriptionExportQueryListVo;
|
|
|
import lombok.AllArgsConstructor;
|
|
|
+import org.apache.commons.lang3.ObjectUtils;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.apache.poi.ss.usermodel.*;
|
|
|
+import org.apache.poi.ss.util.CellRangeAddress;
|
|
|
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
-import java.util.ArrayList;
|
|
|
-import java.util.Arrays;
|
|
|
-import java.util.HashMap;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
-import java.util.TreeMap;
|
|
|
+import java.io.ByteArrayOutputStream;
|
|
|
+import java.io.IOException;
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.util.*;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
+import static com.xjrsoft.module.veb.util.ImportExcelUtil.allFields;
|
|
|
+import static com.xjrsoft.module.veb.util.ImportExcelUtil.createHead;
|
|
|
+
|
|
|
/**
|
|
|
* @title: 班级课程
|
|
|
* @Author brealinxx
|
|
@@ -54,6 +63,8 @@ public class BaseClassCourseServiceImpl extends MPJBaseServiceImpl<BaseClassCour
|
|
|
|
|
|
private final TextbookStudentClaimMapper textbookStudentClaimMapper;
|
|
|
|
|
|
+ private final BaseClassMapper baseClassMapper;
|
|
|
+
|
|
|
@Override
|
|
|
public Page<BaseClassCoursePageVo> getPage(Page<BaseClassCoursePageVo> page, BaseClassCoursePageDto dto) {
|
|
|
return baseClassCourseMapper.getPage(page, dto);
|
|
@@ -254,4 +265,197 @@ public class BaseClassCourseServiceImpl extends MPJBaseServiceImpl<BaseClassCour
|
|
|
public boolean checkExitsWithoutTextbook(Long classId, Long courseId) {
|
|
|
return this.baseMapper.checkExitsWithoutTextbook(classId, courseId);
|
|
|
}
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ByteArrayOutputStream classCourseTextbookExportQuery(ClassCourseTextbookExportQueryDto dto) throws IOException {
|
|
|
+ MPJLambdaWrapper<BaseClass> baseClassCourseMPJLambdaWrapper = new MPJLambdaWrapper<>();
|
|
|
+ baseClassCourseMPJLambdaWrapper
|
|
|
+ .disableSubLogicDel()
|
|
|
+ .selectAs(BaseSemester::getName, ClassCourseTextbookExportQueryVo::getSemester)
|
|
|
+ .selectAs(Department::getName, ClassCourseTextbookExportQueryVo::getDeptName)
|
|
|
+ .selectAs(BaseClass::getId, ClassCourseTextbookExportQueryVo::getClassId)
|
|
|
+ .selectAs(BaseClass::getName, ClassCourseTextbookExportQueryVo::getClassName)
|
|
|
+ .selectAs(BaseCourseSubject::getName, ClassCourseTextbookExportQueryVo::getCourseName)
|
|
|
+ .selectAs(Textbook::getBookName, ClassCourseTextbookExportQueryVo::getTextbookName)
|
|
|
+ .selectAs(Textbook::getUseType, ClassCourseTextbookExportQueryVo::getUseType)
|
|
|
+ .selectAs(Textbook::getPrice, ClassCourseTextbookExportQueryVo::getPrice)
|
|
|
+ .selectAs(Textbook::getDiscountPrice, ClassCourseTextbookExportQueryVo::getDiscountPrice)
|
|
|
+
|
|
|
+ .leftJoin(BaseClassCourse.class, BaseClassCourse::getClassId, BaseClass::getId)
|
|
|
+ .leftJoin(BaseSemester.class, BaseSemester::getId, BaseClassCourse::getBaseSemesterId)
|
|
|
+ .leftJoin(BaseClass.class, BaseClass::getId, BaseClassCourse::getClassId)
|
|
|
+ .leftJoin(Department.class, Department::getId, BaseClass::getOrgId)
|
|
|
+ .leftJoin(BaseCourseSubject.class, BaseCourseSubject::getId, BaseClassCourse::getCourseId)
|
|
|
+ .leftJoin(Textbook.class, Textbook::getId, BaseClassCourse::getTextbookId)
|
|
|
+ .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, Textbook::getTextbookType,
|
|
|
+ wrapper -> wrapper
|
|
|
+ .selectAs(DictionaryDetail::getName, ClassCourseTextbookExportQueryVo::getTextbookType)
|
|
|
+ )
|
|
|
+ .in(ObjectUtils.isNotEmpty(dto.getClassIds()) && !dto.getClassIds().isEmpty(), BaseClassCourse::getClassId, dto.getClassIds())
|
|
|
+ .like(StringUtils.isNotBlank(dto.getClassName()), BaseClass::getName, dto.getClassName())
|
|
|
+ .eq(ObjectUtils.isNotEmpty(dto.getDeptId()), Department::getId, dto.getDeptId())
|
|
|
+ .having(ObjectUtils.isNotEmpty(dto.getCourseSet()) && dto.getCourseSet() == 1, "HAVING LENGTH(course_name) > 0")
|
|
|
+ .having(ObjectUtils.isNotEmpty(dto.getCourseSet()) && dto.getCourseSet() == 2, "HAVING COALESCE(LENGTH(course_name), 0) = 0")
|
|
|
+ .and(ObjectUtils.isNotEmpty(dto.getSemester()),
|
|
|
+ wrapper -> wrapper
|
|
|
+ .eq(BaseClassCourse::getBaseSemesterId, dto.getSemester())
|
|
|
+ .or()
|
|
|
+ .isNull(BaseClassCourse::getBaseSemesterId)
|
|
|
+ )
|
|
|
+ .and(wrapper -> wrapper
|
|
|
+ .eq(BaseClassCourse::getDeleteMark, DeleteMark.NODELETE.getCode())
|
|
|
+ .or()
|
|
|
+ .isNull(BaseClassCourse::getDeleteMark)
|
|
|
+ )
|
|
|
+ .eq(BaseClass::getDeleteMark, DeleteMark.NODELETE.getCode())
|
|
|
+ .orderByDesc(BaseCourseSubject::getName)
|
|
|
+ .orderByDesc(Textbook::getBookName)
|
|
|
+ ;
|
|
|
+
|
|
|
+ List<ClassCourseTextbookExportQueryVo> dataList = baseClassMapper.selectJoinList(ClassCourseTextbookExportQueryVo.class, baseClassCourseMPJLambdaWrapper);
|
|
|
+
|
|
|
+ // 根据班级分组
|
|
|
+ Map<Long, List<ClassCourseTextbookExportQueryVo>> dataMapByClassId = dataList.stream()
|
|
|
+ .collect(Collectors.groupingBy(
|
|
|
+ ClassCourseTextbookExportQueryVo::getClassId,
|
|
|
+ LinkedHashMap::new, // 指定使用LinkedHashMap来保持顺序
|
|
|
+ Collectors.toList()
|
|
|
+ ));
|
|
|
+
|
|
|
+ List<Long> classIds = dataList.stream()
|
|
|
+ .filter(c -> ObjectUtils.isNotEmpty(c.getClassId()))
|
|
|
+ .map(ClassCourseTextbookExportQueryVo::getClassId)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ if(classIds.isEmpty()){
|
|
|
+ throw new MyException("导出数据中班级有误,请刷新重试");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取班级人数
|
|
|
+ MPJLambdaWrapper<BaseStudentSchoolRoll> baseStudentSchoolRollMPJLambdaWrapper = new MPJLambdaWrapper<>();
|
|
|
+ baseStudentSchoolRollMPJLambdaWrapper
|
|
|
+ .selectAs(BaseStudentSchoolRoll::getClassId, BaseStudentSchoolRoll::getClassId)
|
|
|
+ .selectCount(BaseStudentSchoolRoll::getId, BaseStudentSchoolRoll::getDeleteMark)
|
|
|
+ .in(BaseStudentSchoolRoll::getClassId, classIds)
|
|
|
+ .eq(BaseStudentSchoolRoll::getArchivesStatus, ArchivesStatusEnum.FB2901.getCode())
|
|
|
+ .eq(BaseStudentSchoolRoll::getDeleteMark, DeleteMark.NODELETE.getCode())
|
|
|
+ .groupBy(BaseStudentSchoolRoll::getClassId)
|
|
|
+ ;
|
|
|
+ List<BaseStudentSchoolRoll> baseStudentSchoolRolls = baseStudentSchoolRollMapper.selectJoinList(BaseStudentSchoolRoll.class, baseStudentSchoolRollMPJLambdaWrapper);
|
|
|
+
|
|
|
+ Map<Long, Integer> stuNumMap = baseStudentSchoolRolls.stream()
|
|
|
+ .collect(Collectors.toMap(BaseStudentSchoolRoll::getClassId, BaseStudentSchoolRoll::getDeleteMark, (k1,k2) -> k1));
|
|
|
+
|
|
|
+ // 处理数据
|
|
|
+ for (ClassCourseTextbookExportQueryVo c : dataList){
|
|
|
+ // 处理使用学期
|
|
|
+ if(ObjectUtils.isNotEmpty(c.getUseType())){
|
|
|
+ String useType = UseSemesterTypeEnum.getValue(c.getUseType());
|
|
|
+ c.setUseTypeCn(useType);
|
|
|
+ }else {
|
|
|
+ c.setUseTypeCn("未知");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理班级人数
|
|
|
+ Integer stuNum = stuNumMap.get(c.getClassId());
|
|
|
+ if(ObjectUtils.isNotEmpty(stuNum)){
|
|
|
+ c.setStudentNum(stuNum);
|
|
|
+
|
|
|
+ // 处理总价
|
|
|
+ if(ObjectUtils.isNotEmpty(c.getDiscountPrice())){
|
|
|
+ BigDecimal totalPrices = c.getDiscountPrice().multiply(BigDecimal.valueOf(stuNum));
|
|
|
+ c.setTotalPrices(totalPrices);
|
|
|
+ }else {
|
|
|
+ c.setTotalPrices(BigDecimal.ZERO);
|
|
|
+ }
|
|
|
+ }else {
|
|
|
+ c.setStudentNum(0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 开始写入
|
|
|
+ Workbook workbook = new XSSFWorkbook();
|
|
|
+ // 创建一个工作表(sheet)
|
|
|
+ String sheetName = "sheet1";
|
|
|
+ Sheet sheet = workbook.createSheet(sheetName);
|
|
|
+
|
|
|
+ List<ImportConfig> importConfigs = allFields(new ClassCourseTextbookExportQueryVo());
|
|
|
+
|
|
|
+ // 表头
|
|
|
+ createHead(workbook, sheet, importConfigs, 0);
|
|
|
+
|
|
|
+ // 内容
|
|
|
+ int dataRowNumber = 1;
|
|
|
+ Font font = workbook.createFont();
|
|
|
+ font.setFontName("宋体");
|
|
|
+ font.setFontHeightInPoints((short)12);
|
|
|
+
|
|
|
+ CellStyle cellStyle = workbook.createCellStyle();
|
|
|
+ cellStyle.setFont(font); // 将字体应用到样式
|
|
|
+ cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
|
|
|
+ cellStyle.setAlignment(HorizontalAlignment.CENTER);
|
|
|
+
|
|
|
+ for (Map.Entry<Long, List<ClassCourseTextbookExportQueryVo>> entry : dataMapByClassId.entrySet()){
|
|
|
+ Long key = entry.getKey();
|
|
|
+ List<ClassCourseTextbookExportQueryVo> value = entry.getValue();
|
|
|
+ List<List<String>> inList = new ArrayList<>();
|
|
|
+
|
|
|
+ // 小计合计
|
|
|
+ BigDecimal totalDiscountPrice = BigDecimal.ZERO;
|
|
|
+ for (ClassCourseTextbookExportQueryVo c : value){
|
|
|
+ totalDiscountPrice = totalDiscountPrice.add(ObjectUtils.isNotEmpty(c.getDiscountPrice()) ? c.getDiscountPrice() : BigDecimal.ZERO);
|
|
|
+ }
|
|
|
+ for (ClassCourseTextbookExportQueryVo c : value){
|
|
|
+ c.setTotalDiscountPrice(totalDiscountPrice);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 总价合计
|
|
|
+ BigDecimal totalPriceTotal = BigDecimal.ZERO;
|
|
|
+ for (ClassCourseTextbookExportQueryVo c : value){
|
|
|
+ totalPriceTotal = totalPriceTotal.add(ObjectUtils.isNotEmpty(c.getTotalPrices()) ? c.getTotalPrices() : BigDecimal.ZERO);
|
|
|
+ }
|
|
|
+ for (ClassCourseTextbookExportQueryVo c : value){
|
|
|
+ c.setTotalPriceTotal(totalPriceTotal);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 开始写入
|
|
|
+ for (ClassCourseTextbookExportQueryVo c : value){
|
|
|
+ List<String> date = new ArrayList<>();
|
|
|
+ date.add(c.getSemester());
|
|
|
+ date.add(c.getDeptName());
|
|
|
+ date.add(c.getClassName());
|
|
|
+ date.add(c.getCourseName());
|
|
|
+ date.add(c.getTextbookName());
|
|
|
+ date.add(c.getUseTypeCn());
|
|
|
+ date.add(c.getTextbookType());
|
|
|
+ date.add(ObjectUtils.isNotEmpty(c.getPrice()) ? c.getPrice().toString() : "0");
|
|
|
+ date.add(ObjectUtils.isNotEmpty(c.getDiscountPrice()) ? c.getDiscountPrice().toString() : "0");
|
|
|
+ date.add(ObjectUtils.isNotEmpty(c.getTotalDiscountPrice()) ? c.getTotalDiscountPrice().toString() : "0");
|
|
|
+ date.add(c.getStudentNum() + "");
|
|
|
+ date.add(ObjectUtils.isNotEmpty(c.getTotalPrices()) ? c.getTotalPrices().toString() : "0");
|
|
|
+ date.add(ObjectUtils.isNotEmpty(c.getTotalPriceTotal()) ? c.getTotalPriceTotal().toString() : "0");
|
|
|
+ inList.add(date);
|
|
|
+ }
|
|
|
+
|
|
|
+ for (List<String> rowData : inList) {
|
|
|
+ Row dataRow = sheet.createRow(dataRowNumber);
|
|
|
+ for (int i = 0; i < rowData.size(); i++) {
|
|
|
+ sheet.autoSizeColumn(i);
|
|
|
+ Cell cell = dataRow.createCell(i);
|
|
|
+ cell.setCellValue(rowData.get(i));
|
|
|
+ cell.setCellStyle(cellStyle);
|
|
|
+ }
|
|
|
+ dataRowNumber++;
|
|
|
+ }
|
|
|
+ if(inList.size() > 1){
|
|
|
+ sheet.addMergedRegion(new CellRangeAddress(dataRowNumber - inList.size(), dataRowNumber - 1, 9, 9));
|
|
|
+ sheet.addMergedRegion(new CellRangeAddress(dataRowNumber - inList.size(), dataRowNumber - 1, 10, 10));
|
|
|
+ sheet.addMergedRegion(new CellRangeAddress(dataRowNumber - inList.size(), dataRowNumber - 1, 12, 12));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //写入文件
|
|
|
+ ByteArrayOutputStream bot = new ByteArrayOutputStream();
|
|
|
+ workbook.write(bot);
|
|
|
+ return bot;
|
|
|
+ }
|
|
|
}
|