master
小萌新 3 months ago
parent 4e11d014e1
commit b4b07e9522
  1. 12
      src/main/java/com/teaching/backend/controller/chapter/ChapterController2.java
  2. 130
      src/main/java/com/teaching/backend/controller/thumb/SeCourseThumbController.java
  3. 16
      src/main/java/com/teaching/backend/exception/GlobalExceptionHandler.java
  4. 4
      src/main/java/com/teaching/backend/mapper/chapter/ChapterMapper.java
  5. 4
      src/main/java/com/teaching/backend/mapper/courses/CoursesMapper.java
  6. 10
      src/main/java/com/teaching/backend/model/dto/chapter/ChapterDTO.java
  7. 6
      src/main/java/com/teaching/backend/model/dto/chapter/ChapterExcelDTO.java
  8. 4
      src/main/java/com/teaching/backend/model/entity/chapter/Chapter.java
  9. 3
      src/main/java/com/teaching/backend/service/chapter/IChapterService.java
  10. 2
      src/main/java/com/teaching/backend/service/favour/SeCourseFavourService.java
  11. 4
      src/main/java/com/teaching/backend/service/impl/chapter/ChapterExcelServiceImpl.java
  12. 72
      src/main/java/com/teaching/backend/service/impl/chapter/ChapterServiceImpl.java
  13. 208
      src/main/java/com/teaching/backend/service/impl/thumb/SeCourseThumbServiceImpl.java
  14. 66
      src/main/java/com/teaching/backend/service/thumb/SeCourseThumbService.java
  15. 3
      src/main/java/com/teaching/backend/utils/Chapter/ExcelParser.java
  16. 40
      src/main/java/com/teaching/backend/utils/Chapter/SheetHandler.java

@ -15,7 +15,9 @@ import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException; import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
@ -61,9 +63,13 @@ public BaseResponse<List<Chapter>> getCourseChapters2(@RequestParam String cours
@ApiOperation("添加章节") @ApiOperation("添加章节")
@PostMapping("/add") @PostMapping("/add")
public BaseResponse<String> addChapter2(@RequestBody ChapterDTO chapterDTO){ public BaseResponse<String> addChapter2(@Valid @RequestBody ChapterDTO chapterDTO) {
chapterService.saveChapter(chapterDTO); BigDecimal remainingHours = chapterService.saveChapter(chapterDTO);
return ResultUtils.success("添加成功!!!!!!!!"); if (remainingHours.compareTo(BigDecimal.ZERO) == 0) {
return ResultUtils.success("添加成功!所有学时分配完成");
} else {
return ResultUtils.success("添加成功!还剩下" + remainingHours + "学时待分配");
}
} }
@ApiOperation("插入章节") @ApiOperation("插入章节")

@ -1,65 +1,65 @@
//package com.teaching.backend.controller.thumb; package com.teaching.backend.controller.thumb;
//
//import com.teaching.backend.common.BaseResponse; import com.teaching.backend.common.BaseResponse;
//import com.teaching.backend.common.ErrorCode; import com.teaching.backend.common.ErrorCode;
//import com.teaching.backend.exception.BusinessException; import com.teaching.backend.exception.BusinessException;
//import com.teaching.backend.model.dto.thumb.coursethumb.CourseThumbAddRequest; import com.teaching.backend.model.dto.thumb.coursethumb.CourseThumbAddRequest;
//import com.teaching.backend.model.dto.thumb.coursethumb.CourseThumbAllRequest; import com.teaching.backend.model.dto.thumb.coursethumb.CourseThumbAllRequest;
//import com.teaching.backend.service.thumb.SeCourseThumbService; import com.teaching.backend.service.thumb.SeCourseThumbService;
//import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
//import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
//import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
//import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
//import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
//import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
//
//import javax.annotation.Resource; import javax.annotation.Resource;
//
///** /**
// * @Author:youhang * @Author:youhang
// * @Date:2024-05-30-20:22 * @Date:2024-05-30-20:22
// * @Description: * @Description:
// */ */
//@RestController @RestController
//@RequestMapping("/api/course_thumb") @RequestMapping("/api/course_thumb")
//@Slf4j @Slf4j
//public class SeCourseThumbController { public class SeCourseThumbController {
//
// @Resource @Resource
// private SeCourseThumbService seCourseThumbService; private SeCourseThumbService seCourseThumbService;
//
//
// /** /**
// * 点赞/取消点赞 * 点赞/取消点赞
// * *
// * @param courseThumbAddRequest * @param courseThumbAddRequest
// * @return result 执行情况 * @return result 执行情况
// */ */
// @PostMapping("/") @PostMapping("/")
// // HttpServletRequest request 在一个fitter里面进行鉴权操作 // HttpServletRequest request 在一个fitter里面进行鉴权操作
// public BaseResponse<Boolean> doThumb(@RequestBody CourseThumbAddRequest courseThumbAddRequest) { public BaseResponse<Boolean> doThumb(@RequestBody CourseThumbAddRequest courseThumbAddRequest) {
//
// return seCourseThumbService.doCourseThumb(courseThumbAddRequest.getCourseId(), courseThumbAddRequest.getUserId()); return seCourseThumbService.doCourseThumb(courseThumbAddRequest.getCourseId(), courseThumbAddRequest.getUserId());
//
// } }
//
//
// /** /**
// * 课程点赞总数 * 课程点赞总数
// * *
// * @param courseThumbAddRequest * @param courseThumbAddRequest
// * @return result 课程点赞总数 * @return result 课程点赞总数
// */ */
// @PostMapping("/count") @PostMapping("/count")
// // HttpServletRequest request 在一个fitter里面进行鉴权操作 // HttpServletRequest request 在一个fitter里面进行鉴权操作
// public BaseResponse<Long> thumbCount(@RequestBody CourseThumbAddRequest courseThumbAddRequest) { public BaseResponse<Long> thumbCount(@RequestBody CourseThumbAddRequest courseThumbAddRequest) {
// if (StringUtils.isAnyBlank(courseThumbAddRequest.getCourseId())) { if (StringUtils.isAnyBlank(courseThumbAddRequest.getCourseId())) {
// throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数不能为空"); throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数不能为空");
// } }
//
// return seCourseThumbService.thumbCount(courseThumbAddRequest.getCourseId()); return seCourseThumbService.thumbCount(courseThumbAddRequest.getCourseId());
//
// } }
//
//
//} }

@ -5,12 +5,26 @@ import com.teaching.backend.common.ErrorCode;
import com.teaching.backend.common.ResultUtils; import com.teaching.backend.common.ResultUtils;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.HashMap;
import java.util.Map;
@RestControllerAdvice @RestControllerAdvice
public class GlobalExceptionHandler { public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Map<String, String>> handleValidationExceptions(MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
ex.getBindingResult().getAllErrors().forEach((error) -> {
String fieldName = ((FieldError) error).getField();
String errorMessage = error.getDefaultMessage();
errors.put(fieldName, errorMessage);
});
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errors);
}
@ExceptionHandler(BusinessException.class) @ExceptionHandler(BusinessException.class)
public ResponseEntity<ErrorResponse> handleBusinessException(BusinessException ex) { public ResponseEntity<ErrorResponse> handleBusinessException(BusinessException ex) {
ErrorResponse errorResponse = new ErrorResponse(ex.getCode(), ex.getMessage()); ErrorResponse errorResponse = new ErrorResponse(ex.getCode(), ex.getMessage());

@ -7,6 +7,7 @@ import io.lettuce.core.dynamic.annotation.Param;
import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update; import org.apache.ibatis.annotations.Update;
import java.math.BigDecimal;
import java.util.List; import java.util.List;
/** /**
@ -33,4 +34,7 @@ public interface ChapterMapper extends BaseMapper<Chapter> {
Chapter selectByNameAndCourseId(@Param("name") String name, @Param("courseId") String courseId); Chapter selectByNameAndCourseId(@Param("name") String name, @Param("courseId") String courseId);
@Select("select pid ,course_id,total_class_hours from chapter where pid = #{chapterId} and course_id = #{courseId} ") @Select("select pid ,course_id,total_class_hours from chapter where pid = #{chapterId} and course_id = #{courseId} ")
List<Chapter> selectByIdAndPid(@Param("chapterId") Long chapterId, @Param("courseId")String courseId); List<Chapter> selectByIdAndPid(@Param("chapterId") Long chapterId, @Param("courseId")String courseId);
@Select("select total_class_hours from chapter where id=#{pid}")
BigDecimal getChapterHours(@Param("pid") Long pid);
} }

@ -3,12 +3,14 @@ package com.teaching.backend.mapper.courses;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.teaching.backend.model.entity.chapter.Chapter;
import com.teaching.backend.model.entity.courses.Courses; import com.teaching.backend.model.entity.courses.Courses;
import com.teaching.backend.model.vo.courses.CoursesVO; import com.teaching.backend.model.vo.courses.CoursesVO;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Select;
import java.math.BigDecimal;
import java.util.List; import java.util.List;
/** /**
@ -24,5 +26,7 @@ public interface CoursesMapper extends BaseMapper<Courses> {
@Select("SELECT * FROM courses LIMIT #{start}, #{pageSize}") @Select("SELECT * FROM courses LIMIT #{start}, #{pageSize}")
List<Courses> getItemsByPage(@Param("start") int start, @Param("pageSize") int pageSize); List<Courses> getItemsByPage(@Param("start") int start, @Param("pageSize") int pageSize);
@Select("select classhours from courses where id=#{id}")
BigDecimal getClassHoursById(@Param("id") String id);
} }

@ -7,6 +7,9 @@ import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import javax.validation.constraints.Digits;
import javax.validation.constraints.Pattern;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@ -25,6 +28,10 @@ import java.time.LocalDateTime;
public class ChapterDTO implements Serializable { public class ChapterDTO implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Digits(integer = 10, fraction = 1, message = "总学时只能保留一位小数")
@ApiModelProperty(value = "总学时")
private double totalClassHours;
@ApiModelProperty(value = "创建人") @ApiModelProperty(value = "创建人")
private String createBy; private String createBy;
@ -61,8 +68,7 @@ public class ChapterDTO implements Serializable {
@ApiModelProperty(value = "课程目标") @ApiModelProperty(value = "课程目标")
private String courseObjectivesId; private String courseObjectivesId;
@ApiModelProperty(value = "总学时")
private double totalClassHours;
@ApiModelProperty(value = "要求") @ApiModelProperty(value = "要求")
private String requirement; private String requirement;

@ -9,6 +9,8 @@ import lombok.NoArgsConstructor;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
/** /**
* ClassName: ChapterExcelDto * ClassName: ChapterExcelDto
@ -29,6 +31,7 @@ public class ChapterExcelDTO implements Serializable {
private String createBy; private String createBy;
@ApiModelProperty(value = "创建日期") @ApiModelProperty(value = "创建日期")
@JsonFormat(pattern = "yyyy/M/d HH:mm:ss") @JsonFormat(pattern = "yyyy/M/d HH:mm:ss")
private LocalDateTime createTime; private LocalDateTime createTime;
@ -94,7 +97,10 @@ public class ChapterExcelDTO implements Serializable {
@TableField(exist = false) @TableField(exist = false)
private Long ExcelId; private Long ExcelId;
public void setIsSection(boolean b) { public void setIsSection(boolean b) {
this.isSection=b; this.isSection=b;
} }
// 添加获取和设置方法
} }

@ -11,6 +11,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import javax.validation.constraints.Digits;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
@ -70,6 +71,9 @@ public class Chapter implements Serializable {
private String courseObjectivesId; private String courseObjectivesId;
@ApiModelProperty(value = "总学时") @ApiModelProperty(value = "总学时")
//使用参数合法性校验
@Digits(integer = 10, fraction = 1, message = "总学时只能保留一位小数")
// package com.teaching.backend.exception;需要在这个里面添加异常处理
private double totalClassHours; private double totalClassHours;
@ApiModelProperty(value = "要求") @ApiModelProperty(value = "要求")

@ -10,6 +10,7 @@ import com.teaching.backend.model.vo.chapter.ChapterVo;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.math.BigDecimal;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@ -33,7 +34,7 @@ public interface IChapterService extends IService<Chapter> {
List<Chapter> getChapterTree(String courseId); List<Chapter> getChapterTree(String courseId);
void saveChapter(ChapterDTO chapterDTO); BigDecimal saveChapter(ChapterDTO chapterDTO);

@ -8,6 +8,7 @@ import com.teaching.backend.model.entity.courses.Courses;
import com.teaching.backend.model.entity.favour.SeCourseFavour; import com.teaching.backend.model.entity.favour.SeCourseFavour;
import com.teaching.backend.model.vo.courses.CoursesVO; import com.teaching.backend.model.vo.courses.CoursesVO;
import com.teaching.backend.model.vo.favour.CourseFavourDetailVO; import com.teaching.backend.model.vo.favour.CourseFavourDetailVO;
import org.springframework.stereotype.Service;
import java.util.List; import java.util.List;
@ -16,6 +17,7 @@ import java.util.List;
* @Date:2024-05-30-20:22 * @Date:2024-05-30-20:22
* @Description: * @Description:
*/ */
public interface SeCourseFavourService extends IService<SeCourseFavour> { public interface SeCourseFavourService extends IService<SeCourseFavour> {
/** /**

@ -26,7 +26,9 @@ public class ChapterExcelServiceImpl {
public List<String> uploadExcel(MultipartFile file, String courseId) { public List<String> uploadExcel(MultipartFile file, String courseId) {
List<String> validationErrors = new ArrayList<>(); List<String> validationErrors = new ArrayList<>();
try (InputStream inputStream = file.getInputStream()) { try (
InputStream inputStream = file.getInputStream()
) {
validationErrors = excelParser.parse(inputStream, courseId); validationErrors = excelParser.parse(inputStream, courseId);
} catch (Exception e) { } catch (Exception e) {
validationErrors.add("系统错误: " + e.getMessage()); validationErrors.add("系统错误: " + e.getMessage());

@ -12,6 +12,7 @@ import com.teaching.backend.exception.BusinessException;
import com.teaching.backend.mapper.Knowtemp.KnowtmpMapper; import com.teaching.backend.mapper.Knowtemp.KnowtmpMapper;
import com.teaching.backend.mapper.chapter.ChapterMapper; import com.teaching.backend.mapper.chapter.ChapterMapper;
import com.teaching.backend.mapper.chapter.TemporaryChapterMapper; import com.teaching.backend.mapper.chapter.TemporaryChapterMapper;
import com.teaching.backend.mapper.courses.CoursesMapper;
import com.teaching.backend.model.dto.chapter.ChapterDTO; import com.teaching.backend.model.dto.chapter.ChapterDTO;
import com.teaching.backend.model.dto.chapter.ChapterExcelDTO; import com.teaching.backend.model.dto.chapter.ChapterExcelDTO;
@ -29,6 +30,8 @@ import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -44,6 +47,8 @@ public class ChapterServiceImpl extends ServiceImpl<ChapterMapper, Chapter> impl
@Autowired @Autowired
private ChapterMapper chapterMapper; private ChapterMapper chapterMapper;
@Autowired
private CoursesMapper coursesMapper;
@Autowired @Autowired
private TemporaryChapterMapper temporaryChapterMapper; private TemporaryChapterMapper temporaryChapterMapper;
@Autowired @Autowired
@ -228,8 +233,7 @@ public class ChapterServiceImpl extends ServiceImpl<ChapterMapper, Chapter> impl
} }
@Override @Override
public void saveChapter(ChapterDTO chapterDTO) { public BigDecimal saveChapter(ChapterDTO chapterDTO) {
Chapter chapter = new Chapter(); Chapter chapter = new Chapter();
try { try {
BeanUtils.copyProperties(chapterDTO, chapter); BeanUtils.copyProperties(chapterDTO, chapter);
@ -237,7 +241,27 @@ public class ChapterServiceImpl extends ServiceImpl<ChapterMapper, Chapter> impl
throw new RuntimeException("复制数据出错", e); throw new RuntimeException("复制数据出错", e);
} }
Long pid = chapter.getPid(); Long pid = chapter.getPid();
BigDecimal remainingHours = BigDecimal.ZERO; // 初始化剩余学时
if (pid == null) { if (pid == null) {
BigDecimal classHours = coursesMapper.getClassHoursById(chapterDTO.getCourseId());
LambdaQueryWrapper<Chapter> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(Chapter::getPid, 0)
.eq(Chapter::getCourseId, chapterDTO.getCourseId());
List<Chapter> chapterList = chapterMapper.selectList(lambdaQueryWrapper);
BigDecimal totalChapterHours = chapterList.stream()
.map(Chapter::getTotalClassHours)
.map(BigDecimal::new)
.reduce(BigDecimal.ZERO, BigDecimal::add);
remainingHours = classHours.subtract(totalChapterHours).setScale(1, RoundingMode.HALF_UP);
if (totalChapterHours.compareTo(classHours) < 0) {
chapter.setPid(0L); chapter.setPid(0L);
LambdaQueryWrapper<Chapter> maxSortWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<Chapter> maxSortWrapper = new LambdaQueryWrapper<>();
maxSortWrapper.eq(Chapter::getPid, 0).orderByDesc(Chapter::getOrderNum).last("limit 1"); maxSortWrapper.eq(Chapter::getPid, 0).orderByDesc(Chapter::getOrderNum).last("limit 1");
@ -249,36 +273,65 @@ public class ChapterServiceImpl extends ServiceImpl<ChapterMapper, Chapter> impl
chapter.setOrderNum(newSort); chapter.setOrderNum(newSort);
chapter.setCreateTime(LocalDateTime.now()); chapter.setCreateTime(LocalDateTime.now());
chapter.setUpdateTime(LocalDateTime.now()); chapter.setUpdateTime(LocalDateTime.now());
this.save(chapter); this.save(chapter);
} else { } else {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "当前课程的总学时已经分配完成,请先修改章节学时,或者课程总学时");
}
} else {
BigDecimal chapterHours = chapterMapper.getChapterHours(pid);
LambdaQueryWrapper<Chapter> chapterLambdaQueryWrapper = new LambdaQueryWrapper<>();
chapterLambdaQueryWrapper.eq(Chapter::getPid, pid)
.eq(Chapter::getCourseId, chapterDTO.getCourseId());
List<Chapter> chapterList = chapterMapper.selectList(chapterLambdaQueryWrapper);
BigDecimal hours = chapterList.stream()
.map(Chapter::getTotalClassHours)
.map(BigDecimal::new)
.reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal totalClassHours = new BigDecimal(chapterDTO.getTotalClassHours()).setScale(1, RoundingMode.HALF_UP);
remainingHours = chapterHours.subtract(hours).setScale(1, RoundingMode.HALF_UP);
if (remainingHours.compareTo(totalClassHours) >= 0) {
Chapter parentChapter = this.getById(pid); Chapter parentChapter = this.getById(pid);
if (parentChapter != null) { if (parentChapter != null) {
LambdaQueryWrapper<Chapter> maxSortWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<Chapter> maxSortWrapper = new LambdaQueryWrapper<>();
maxSortWrapper.eq(Chapter::getPid, pid).orderByDesc(Chapter::getOrderNum).last("limit 1"); maxSortWrapper.eq(Chapter::getPid, pid).orderByDesc(Chapter::getOrderNum).last("limit 1");
parentChapter.setUpdateTime(LocalDateTime.now()); parentChapter.setUpdateTime(LocalDateTime.now());
Chapter maxSortChapter = this.getOne(maxSortWrapper); Chapter maxSortChapter = this.getOne(maxSortWrapper);
double newSort = 1; double newSort = 1;
if (maxSortChapter != null) { if (maxSortChapter != null) {
newSort = maxSortChapter.getOrderNum() + 1; newSort = maxSortChapter.getOrderNum() + 1;
} }
chapter.setOrderNum(newSort); chapter.setOrderNum(newSort);
this.updateById(parentChapter); this.updateById(parentChapter);
chapter.setCreateTime(LocalDateTime.now()); chapter.setCreateTime(LocalDateTime.now());
chapter.setUpdateTime(LocalDateTime.now()); chapter.setUpdateTime(LocalDateTime.now());
this.save(chapter); this.save(chapter);
remainingHours = remainingHours.subtract(totalClassHours).setScale(1, RoundingMode.HALF_UP);
} else { } else {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "未找到父章节,ID 为: " + pid); throw new BusinessException(ErrorCode.PARAMS_ERROR, "未找到父章节,ID 为: " + pid);
} }
} else {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "所添加的章节学时大于其父章节剩余学时,所添加学时为:" + totalClassHours + " 父章节学时为:" + chapterHours +
" 当前所剩学时为:" + remainingHours);
} }
} }
return remainingHours;
}
@Override @Override
public Long saveExcelChapter2(ChapterDTO chapterDTO, boolean isParent) { public Long saveExcelChapter2(ChapterDTO chapterDTO, boolean isParent) {
Chapter chapter = new Chapter(); Chapter chapter = new Chapter();
@ -477,6 +530,7 @@ public class ChapterServiceImpl extends ServiceImpl<ChapterMapper, Chapter> impl
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void moveDataFromTemporaryToFinal() { public void moveDataFromTemporaryToFinal() {
List<TemporaryChapter> temporaryChapters = temporaryChapterMapper.selectAll(); List<TemporaryChapter> temporaryChapters = temporaryChapterMapper.selectAll();
Map<Long, Long> tempIdToFinalIdMap = new HashMap<>(); Map<Long, Long> tempIdToFinalIdMap = new HashMap<>();
for (TemporaryChapter tempChapter : temporaryChapters) { for (TemporaryChapter tempChapter : temporaryChapters) {
@ -537,7 +591,7 @@ public class ChapterServiceImpl extends ServiceImpl<ChapterMapper, Chapter> impl
temporaryChapter.setPid(parentChapter.getId()); temporaryChapter.setPid(parentChapter.getId());
setChapterOrder(temporaryChapter, pid); setChapterOrder(temporaryChapter, pid);
} else { } else {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "未找到父章节,ID 为: " + pid); throw new BusinessException(ErrorCode.PARAMS_ERROR, "在这里报的错 未找到父章节,ID 为: " + pid);
} }
} }
// 执行 // 执行

@ -1,108 +1,100 @@
//package com.teaching.backend.service.impl.thumb; package com.teaching.backend.service.impl.thumb;
//
//import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
//import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
//import com.teaching.backend.common.BaseResponse; import com.teaching.backend.common.BaseResponse;
//import com.teaching.backend.common.ErrorCode; import com.teaching.backend.common.ErrorCode;
//import com.teaching.backend.common.ResultUtils; import com.teaching.backend.common.ResultUtils;
//import com.teaching.backend.exception.BusinessException; import com.teaching.backend.exception.BusinessException;
//import com.teaching.backend.mapper.courses.CoursesMapper; import com.teaching.backend.mapper.courses.CoursesMapper;
//import com.teaching.backend.mapper.thumb.SeCourseThumbMapper; import com.teaching.backend.mapper.thumb.SeCourseThumbMapper;
//import com.teaching.backend.model.entity.courses.Courses; import com.teaching.backend.model.entity.courses.Courses;
//import com.teaching.backend.model.entity.thumb.SeCourseThumb; import com.teaching.backend.model.entity.thumb.SeCourseThumb;
//import com.teaching.backend.model.entity.thumb.SeKnowThumb; import com.teaching.backend.model.entity.thumb.SeKnowThumb;
//import com.teaching.backend.model.entity.thumb.SeResourceThumb; import com.teaching.backend.model.entity.thumb.SeResourceThumb;
//import com.teaching.backend.service.thumb.SeCourseThumbService; import com.teaching.backend.service.thumb.SeCourseThumbService;
//import com.teaching.backend.service.thumb.SeKnowThumbService; import org.springframework.beans.factory.annotation.Autowired;
//import com.teaching.backend.service.thumb.SeResourceThumbService; import org.springframework.stereotype.Service;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Service; import javax.annotation.Resource;
// import java.util.concurrent.locks.Lock;
//import javax.annotation.Resource; import java.util.concurrent.locks.ReentrantLock;
//import java.util.concurrent.locks.Lock;
//import java.util.concurrent.locks.ReentrantLock;
// /**
// * @Author:youhang
///** * @Date:2024-05-30-20:23
// * @Author:youhang * @Description:
// * @Date:2024-05-30-20:23 */
// * @Description: @Service
// */ public class SeCourseThumbServiceImpl extends ServiceImpl<SeCourseThumbMapper, SeCourseThumb> implements SeCourseThumbService {
//@Service
//public class SeCourseThumbServiceImpl extends ServiceImpl<SeCourseThumbMapper, SeCourseThumb> implements SeCourseThumbService {
//
// @Autowired
// @Resource CoursesMapper coursesMapper;
// private SeResourceThumbService seResourceThumbService;
// @Override
// @Resource public BaseResponse<Boolean> doCourseThumb(String courseId, String userId) {
// SeKnowThumbService seKnowThumbService;
// //从数据库中校验是否存在courseid
// Courses courses = coursesMapper.selectById(courseId);
// @Autowired boolean result = false;
// CoursesMapper coursesMapper; if(courses == null){
// return ResultUtils.error(ErrorCode.PARAMS_COURSE_NOTEXISTS);
// @Override }
// public BaseResponse<Boolean> doCourseThumb(String courseId, String userId) {
// // 先查询数据库记录,该用户是否点赞
// //从数据库中校验是否存在courseid SeCourseThumb seCourseThumb = new SeCourseThumb();
// Courses courses = coursesMapper.selectById(courseId); seCourseThumb.setCourseId(courseId);
// boolean result = false; seCourseThumb.setUserId(userId);
// if(courses == null){ QueryWrapper<SeCourseThumb> thumbQueryWrapper = new QueryWrapper<>(seCourseThumb);
// return ResultUtils.error(ErrorCode.PARAMS_COURSE_NOTEXISTS); SeCourseThumb oldSeCourseThumb = this.getOne(thumbQueryWrapper);
// } //已点赞
// if (oldSeCourseThumb != null) {
// // 先查询数据库记录,该用户是否点赞 // 取消点赞 删除记录
// SeCourseThumb seCourseThumb = new SeCourseThumb(); result = this.remove(thumbQueryWrapper);
// seCourseThumb.setCourseId(courseId); if (result) {
// seCourseThumb.setUserId(userId); System.out.println("取消点赞成功");
// QueryWrapper<SeCourseThumb> thumbQueryWrapper = new QueryWrapper<>(seCourseThumb); return ResultUtils.success(result);
// SeCourseThumb oldSeCourseThumb = this.getOne(thumbQueryWrapper); } else {
// //已点赞 throw new BusinessException(ErrorCode.SYSTEM_ERROR);
// if (oldSeCourseThumb != null) { }
// // 取消点赞 删除记录 } else {
// result = this.remove(thumbQueryWrapper); // 每个用户串行点赞
// if (result) { // 锁必须要包裹住事务方法
// System.out.println("取消点赞成功"); Lock lock = new ReentrantLock();
// return ResultUtils.success(result); lock.lock();
// } else { try {
// throw new BusinessException(ErrorCode.SYSTEM_ERROR); result = this.save(seCourseThumb);
// } } catch (Exception e) {
// } else { throw new BusinessException(ErrorCode.OPERATION_ERROR);
// // 每个用户串行点赞 } finally {
// // 锁必须要包裹住事务方法 lock.unlock();
// Lock lock = new ReentrantLock(); System.out.println("点赞成功");
// lock.lock(); return ResultUtils.success(result);
// try { }
// result = this.save(seCourseThumb); }
// } catch (Exception e) { }
// throw new BusinessException(ErrorCode.OPERATION_ERROR);
// } finally { @Override
// lock.unlock(); public BaseResponse<Long> thumbCount(String courseId) {
// System.out.println("点赞成功");
// return ResultUtils.success(result); //从数据库中校验是否存在courseid
// } Courses courses = coursesMapper.selectById(courseId);
// } if(courses == null){
// } return ResultUtils.error(ErrorCode.PARAMS_COURSE_NOTEXISTS);
// }
// @Override
// public BaseResponse<Long> thumbCount(String courseId) { QueryWrapper<SeCourseThumb> thumbQueryWrapper = new QueryWrapper<>();
// thumbQueryWrapper.eq("course_id", courseId);
// //从数据库中校验是否存在courseid long count = this.count(thumbQueryWrapper);
// Courses courses = coursesMapper.selectById(courseId); if (count == 0) {
// if(courses == null){ throw new BusinessException(ErrorCode.SYSTEM_ERROR, "查询参数不存在");
// return ResultUtils.error(ErrorCode.PARAMS_COURSE_NOTEXISTS); } else {
// } return ResultUtils.success(count);
// }
// QueryWrapper<SeCourseThumb> thumbQueryWrapper = new QueryWrapper<>(); }
// thumbQueryWrapper.eq("course_id", courseId);
// long count = this.count(thumbQueryWrapper);
// if (count == 0) { }
// throw new BusinessException(ErrorCode.SYSTEM_ERROR, "查询参数不存在");
// } else {
// return ResultUtils.success(count);
// }
// }
//
//
//}

@ -1,33 +1,33 @@
//package com.teaching.backend.service.thumb; package com.teaching.backend.service.thumb;
//
//import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
//import com.teaching.backend.common.BaseResponse; import com.teaching.backend.common.BaseResponse;
//import com.teaching.backend.model.entity.thumb.SeCourseThumb; import com.teaching.backend.model.entity.thumb.SeCourseThumb;
//
///** /**
// * @Author:youhang * @Author:youhang
// * @Date:2024-05-30-20:22 * @Date:2024-05-30-20:22
// * @Description: * @Description:
// */ */
//public interface SeCourseThumbService extends IService<SeCourseThumb> { public interface SeCourseThumbService extends IService<SeCourseThumb> {
//
// /** /**
// * 点赞 * 点赞
// * *
// * @param courseId * @param courseId
// * @param userId * @param userId
// * @return * @return
// */ */
// BaseResponse<Boolean> doCourseThumb(String courseId, String userId); BaseResponse<Boolean> doCourseThumb(String courseId, String userId);
//
//
// /** /**
// * 点赞总数 * 点赞总数
// * *
// * @param courseId * @param courseId
// * @return * @return
// */ */
// BaseResponse<Long> thumbCount(String courseId); BaseResponse<Long> thumbCount(String courseId);
//
//
//} }

@ -13,13 +13,10 @@ package com.teaching.backend.utils.Chapter;
import com.teaching.backend.mapper.chapter.TemporaryChapterMapper; import com.teaching.backend.mapper.chapter.TemporaryChapterMapper;
import com.teaching.backend.service.chapter.IChapterService; import com.teaching.backend.service.chapter.IChapterService;
import org.apache.poi.openxml4j.opc.OPCPackage; 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.XSSFReader;
import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler; import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler;
import org.apache.poi.xssf.model.SharedStringsTable; import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.model.StylesTable; import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.xml.sax.InputSource; import org.xml.sax.InputSource;

@ -16,6 +16,7 @@ import org.apache.poi.xssf.usermodel.XSSFComment;
import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.*; import java.util.*;
/** /**
@ -32,7 +33,6 @@ public class SheetHandler implements XSSFSheetXMLHandler.SheetContentsHandler {
private Long currentChapterPid; private Long currentChapterPid;
private final TemporaryChapterMapper temporaryChapterMapper; private final TemporaryChapterMapper temporaryChapterMapper;
private Double chapterHour;
private final IChapterService chapterService; private final IChapterService chapterService;
private final String courseId; private final String courseId;
private ChapterExcelDTO chapterDTO; private ChapterExcelDTO chapterDTO;
@ -41,6 +41,9 @@ public class SheetHandler implements XSSFSheetXMLHandler.SheetContentsHandler {
private boolean hasErrors = false; private boolean hasErrors = false;
private int totalRows; private int totalRows;
// 用于存储章节的学时总和
private BigDecimal allHours = BigDecimal.ZERO;
private BigDecimal expectedTotalClassHours=BigDecimal.ZERO;
public SheetHandler(TemporaryChapterMapper temporaryChapterMapper, IChapterService chapterService, String courseId,int totalRows) { public SheetHandler(TemporaryChapterMapper temporaryChapterMapper, IChapterService chapterService, String courseId,int totalRows) {
@ -55,6 +58,8 @@ public class SheetHandler implements XSSFSheetXMLHandler.SheetContentsHandler {
if (rowIndex < totalRows - 1) { if (rowIndex < totalRows - 1) {
if (rowIndex == 0 || rowIndex == 1) { if (rowIndex == 0 || rowIndex == 1) {
chapterDTO = null; chapterDTO = null;
allHours = BigDecimal.ZERO; // 重置学时总和
expectedTotalClassHours = BigDecimal.ZERO; // 重置预期学时
} else { } else {
chapterDTO = new ChapterExcelDTO(); chapterDTO = new ChapterExcelDTO();
chapterDTO.setCourseId(courseId); chapterDTO.setCourseId(courseId);
@ -67,6 +72,9 @@ public class SheetHandler implements XSSFSheetXMLHandler.SheetContentsHandler {
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public List<String> finalizeProcess() { public List<String> finalizeProcess() {
// 校验学时
validateTotalClassHours();
if (hasErrors) { if (hasErrors) {
return validationErrors; return validationErrors;
} }
@ -75,6 +83,16 @@ public class SheetHandler implements XSSFSheetXMLHandler.SheetContentsHandler {
return Collections.emptyList(); return Collections.emptyList();
} }
private void validateTotalClassHours() {
if (allHours.subtract(expectedTotalClassHours).abs().compareTo(BigDecimal.valueOf(0.01)) > 0) {
validationErrors.add("学时总和不匹配: 实际总和为 " + allHours + ", 预期为 " + expectedTotalClassHours);
temporaryChapterMapper.deleteAll();
hasErrors = true;
}
}
private void saveToTemporaryTable(ChapterExcelDTO chapterDTO) { private void saveToTemporaryTable(ChapterExcelDTO chapterDTO) {
Long pid = chapterDTO.getParentExcelId(); Long pid = chapterDTO.getParentExcelId();
if (pid != null && pid != 0) { if (pid != null && pid != 0) {
@ -107,7 +125,6 @@ public class SheetHandler implements XSSFSheetXMLHandler.SheetContentsHandler {
if (chapterDTO.isSection()) { if (chapterDTO.isSection()) {
if (currentChapterPid != null) { if (currentChapterPid != null) {
chapterDTO.setTotalClassHours(chapterHour);
chapterDTO.setPid(currentChapterPid); chapterDTO.setPid(currentChapterPid);
saveToTemporaryTable(chapterDTO); saveToTemporaryTable(chapterDTO);
} else { } else {
@ -134,7 +151,12 @@ public class SheetHandler implements XSSFSheetXMLHandler.SheetContentsHandler {
case "C": case "C":
if (!chapterDTO.isSection()) { if (!chapterDTO.isSection()) {
chapterDTO.setTotalClassHours(Double.parseDouble(formattedValue)); // 当前章节的学时
BigDecimal classHours = new BigDecimal(formattedValue);
chapterDTO.setTotalClassHours(classHours.doubleValue());
expectedTotalClassHours = expectedTotalClassHours.add(classHours); // 累加预期学时
saveToTemporaryTable(chapterDTO); saveToTemporaryTable(chapterDTO);
currentChapterPid = excelIdToDatabaseIdMap.get(chapterDTO.getExcelId()); currentChapterPid = excelIdToDatabaseIdMap.get(chapterDTO.getExcelId());
} }
@ -153,16 +175,18 @@ public class SheetHandler implements XSSFSheetXMLHandler.SheetContentsHandler {
case "F": case "F":
if (chapterDTO.isSection()) { if (chapterDTO.isSection()) {
chapterDTO.setTotalClassHours(Double.parseDouble(formattedValue)); // 子章节的学时
chapterHour = chapterDTO.getTotalClassHours(); BigDecimal sectionHours = new BigDecimal(formattedValue);
chapterDTO.setTotalClassHours(sectionHours.doubleValue());
// 只对当前章节的学时进行累加
allHours = allHours.add(sectionHours);
System.out.println("这是累加的学时" + allHours);
} }
break; break;
} }
} }
} }
} }
Loading…
Cancel
Save