SlideServiceImpl.java 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. package nju.seec.helper.service.impl;
  2. import com.google.common.collect.ImmutableSet;
  3. import lombok.Cleanup;
  4. import lombok.SneakyThrows;
  5. import nju.seec.helper.dao.ChooseDAO;
  6. import nju.seec.helper.dao.CourseDAO;
  7. import nju.seec.helper.dao.SlideDAO;
  8. import nju.seec.helper.dto.LoginUser;
  9. import nju.seec.helper.dto.ModifySlideDTO;
  10. import nju.seec.helper.dto.SlideDTO;
  11. import nju.seec.helper.dto.SlideStateDTO;
  12. import nju.seec.helper.entity.Course;
  13. import nju.seec.helper.entity.Slide;
  14. import nju.seec.helper.service.AuthUtil;
  15. import nju.seec.helper.service.SlideService;
  16. import nju.seec.helper.util.CacheUtils;
  17. import nju.seec.helper.util.Consts;
  18. import nju.seec.helper.util.FileUtils;
  19. import nju.seec.helper.util.enums.ExceptionType;
  20. import nju.seec.helper.util.enums.SlideState;
  21. import nju.seec.helper.util.exception.HelperException;
  22. import nju.seec.helper.vo.SlideVO;
  23. import org.apache.pdfbox.pdmodel.PDDocument;
  24. import org.springframework.data.domain.Page;
  25. import org.springframework.data.domain.Pageable;
  26. import org.springframework.stereotype.Service;
  27. import org.springframework.transaction.annotation.Transactional;
  28. import org.springframework.web.multipart.MultipartFile;
  29. import java.io.InputStream;
  30. import java.time.LocalDateTime;
  31. import java.util.Objects;
  32. import java.util.concurrent.TimeUnit;
  33. /**
  34. * @author cst
  35. */
  36. @Service
  37. public class SlideServiceImpl implements SlideService {
  38. private static final long SLIDE_URL_LIVING_SECONDS = 20 * 60;
  39. private final CourseDAO courseDAO;
  40. private final SlideDAO slideDAO;
  41. private final ChooseDAO chooseDAO;
  42. private final FileUtils fileUtils;
  43. private final CacheUtils cacheUtils;
  44. public SlideServiceImpl(CourseDAO courseDAO, SlideDAO slideDAO, ChooseDAO chooseDAO, FileUtils fileUtils, CacheUtils cacheUtils) {
  45. this.courseDAO = courseDAO;
  46. this.slideDAO = slideDAO;
  47. this.chooseDAO = chooseDAO;
  48. this.fileUtils = fileUtils;
  49. this.cacheUtils = cacheUtils;
  50. }
  51. @Transactional(rollbackFor = Exception.class)
  52. @SneakyThrows
  53. @Override
  54. public SlideVO createSlide(LoginUser teacher, SlideDTO slideDTO) {
  55. Course course = courseDAO.findCourseById(slideDTO.getCourseId());
  56. AuthUtil.checkDataAuth(teacher.getId(), course.getTeacherId(), "您无权创建该课程的幻灯片");
  57. Slide slide = new Slide()
  58. .setCourseId(slideDTO.getCourseId())
  59. .setCourseName(course.getName())
  60. .setTeacherId(teacher.getId())
  61. .setTeacherName(teacher.getName())
  62. .setName(slideDTO.getName())
  63. .setState(slideDTO.getState());
  64. // 解析文件页数
  65. MultipartFile file = slideDTO.getFile();
  66. int pages;
  67. switch (Objects.requireNonNull(file.getContentType())) {
  68. // pdf
  69. case "application/pdf":
  70. @Cleanup InputStream fileInputStream = file.getInputStream();
  71. PDDocument doc = PDDocument.load(fileInputStream);
  72. pages = doc.getNumberOfPages();
  73. break;
  74. default:
  75. throw HelperException.of(ExceptionType.FORBIDDEN, "不支持的文件类型");
  76. }
  77. slide.setPages(pages);
  78. // 上传文件
  79. String objectName = fileUtils.upload(LocalDateTime.now().toString() + "-" + file.getOriginalFilename(), file.getInputStream());
  80. slide.setObjectName(objectName);
  81. return new SlideVO(slideDAO.save(slide));
  82. }
  83. @Transactional(rollbackFor = Exception.class)
  84. @Override
  85. public SlideVO modifySlide(LoginUser user, ModifySlideDTO modifySlideDTO) {
  86. Slide slide = slideDAO.findSlideById(modifySlideDTO.getId());
  87. AuthUtil.checkDataAuth(user.getId(), slide.getTeacherId(), "您无权修改该幻灯片");
  88. slide.setName(modifySlideDTO.getName());
  89. slide = slideDAO.save(slide);
  90. return new SlideVO(slide);
  91. }
  92. @Transactional(rollbackFor = Exception.class)
  93. @Override
  94. public void modifySlideState(LoginUser user, SlideStateDTO slideStateDTO) {
  95. Slide slide = slideDAO.findSlideById(slideStateDTO.getId());
  96. AuthUtil.checkDataAuth(user.getId(), slide.getTeacherId(), "您无权修改该幻灯片状态");
  97. slide.setState(slideStateDTO.getState());
  98. slideDAO.save(slide);
  99. }
  100. @Transactional(rollbackFor = Exception.class)
  101. @Override
  102. public void removeSlide(LoginUser user, Integer slideId) {
  103. Slide slide = slideDAO.findSlideById(slideId);
  104. AuthUtil.checkDataAuth(user.getId(), slide.getTeacherId(), "您无权删除该幻灯片");
  105. slide.setDeleteAt(System.currentTimeMillis());
  106. slideDAO.save(slide);
  107. }
  108. @Transactional(readOnly = true)
  109. @Override
  110. public Page<SlideVO> teacherGetSlides(LoginUser teacher, String key, Pageable pageable) {
  111. return slideDAO.findByTeacherIdAndNameContains(teacher.getId(), key, pageable).map(SlideVO::new);
  112. }
  113. @Transactional(readOnly = true)
  114. @Override
  115. public Page<SlideVO> teacherGetSlidesByCourse(LoginUser teacher, Integer courseId, String key, Pageable pageable) {
  116. return slideDAO.findByCourseIdAndTeacherIdAndNameContains(courseId, teacher.getId(), key, pageable).map(SlideVO::new);
  117. }
  118. @Transactional(readOnly = true)
  119. @Override
  120. public Page<SlideVO> studentGetSlidesByCourse(LoginUser student, Integer courseId, String key, Pageable pageable) {
  121. if (!chooseDAO.existsByStudentIdAndCourseId(student.getId(), courseId)) {
  122. throw HelperException.of(ExceptionType.FORBIDDEN, "你无权查看该课程下的幻灯片");
  123. }
  124. return slideDAO.findByCourseIdAndStateNotInAndNameContains(courseId, ImmutableSet.of(SlideState.DRAFT), key, pageable).map(SlideVO::new);
  125. }
  126. @Transactional(readOnly = true)
  127. @Override
  128. public String getSlideUrl(LoginUser user, Integer slideId) {
  129. Slide slide = slideDAO.findSlideById(slideId);
  130. checkDataAccessAuth(user, slide);
  131. String url = cacheUtils.get(Consts.SLIDE_URL_CACHE_NAME, slide.getObjectName());
  132. if (url != null) {
  133. return url;
  134. }
  135. url = fileUtils.getUrl(slide.getObjectName(), SLIDE_URL_LIVING_SECONDS);
  136. cacheUtils.set(Consts.SLIDE_URL_CACHE_NAME, slide.getObjectName(), url, SLIDE_URL_LIVING_SECONDS, TimeUnit.SECONDS);
  137. return url;
  138. }
  139. @Transactional(readOnly = true)
  140. @Override
  141. public SlideVO getOneSlide(LoginUser user, Integer slideId) {
  142. Slide slide = slideDAO.findSlideById(slideId);
  143. checkDataAccessAuth(user, slide);
  144. return new SlideVO(slide);
  145. }
  146. private void checkDataAccessAuth(LoginUser user, Slide slide) {
  147. HelperException forbiddenEx = HelperException.of(ExceptionType.FORBIDDEN, "您无权访问该幻灯片");
  148. switch (user.getType()) {
  149. case TEACHER:
  150. if (!slide.getTeacherId().equals(user.getId())) {
  151. throw forbiddenEx;
  152. }
  153. break;
  154. case STUDENT:
  155. if (!chooseDAO.existsByStudentIdAndCourseId(user.getId(), slide.getCourseId())
  156. || slide.getState() == SlideState.DRAFT) {
  157. throw forbiddenEx;
  158. }
  159. break;
  160. default:
  161. throw forbiddenEx;
  162. }
  163. }
  164. }