Browse Source

refactor: 工具类重构

ChenSiTong 6 năm trước cách đây
mục cha
commit
41d0d38701
23 tập tin đã thay đổi với 128 bổ sung117 xóa
  1. 6 0
      pom.xml
  2. 2 1
      src/main/java/nju/seec/helper/api/bok/BokKnowledgeApi.java
  3. 10 5
      src/main/java/nju/seec/helper/api/bok/BokQuestionApi.java
  4. 0 22
      src/main/java/nju/seec/helper/config/PageableConfig.java
  5. 6 0
      src/main/java/nju/seec/helper/controller/QuestionController.java
  6. 1 1
      src/main/java/nju/seec/helper/controller/QuizController.java
  7. 17 0
      src/main/java/nju/seec/helper/dto/quiz/QuizStudentAnswerDTO.java
  8. 3 0
      src/main/java/nju/seec/helper/entity/CourseFile.java
  9. 3 0
      src/main/java/nju/seec/helper/entity/Notice.java
  10. 8 0
      src/main/java/nju/seec/helper/service/QuestionService.java
  11. 2 2
      src/main/java/nju/seec/helper/service/impl/AdminServiceImpl.java
  12. 7 2
      src/main/java/nju/seec/helper/service/impl/QuestionServiceImpl.java
  13. 16 6
      src/main/java/nju/seec/helper/service/impl/SlideServiceImpl.java
  14. 4 4
      src/main/java/nju/seec/helper/service/impl/UserServiceImpl.java
  15. 0 25
      src/main/java/nju/seec/helper/util/EncryptUtils.java
  16. 7 2
      src/main/java/nju/seec/helper/util/JsonUtils.java
  17. 6 5
      src/main/java/nju/seec/helper/util/cache/GuavaCacheUtils.java
  18. 17 16
      src/main/java/nju/seec/helper/util/file/FileUtils.java
  19. 3 4
      src/main/java/nju/seec/helper/util/oss/OssObjectUrlUtils.java
  20. 0 21
      src/main/java/nju/seec/helper/util/serializer/LocalDateTimeSerializer.java
  21. 2 1
      src/main/java/nju/seec/helper/vo/question/TrueOrFalseQuestionVO.java
  22. 4 0
      src/main/resources/application-deploy.yml
  23. 4 0
      src/main/resources/application-dev.yml

+ 6 - 0
pom.xml

@@ -129,6 +129,12 @@
             <groupId>org.ehcache</groupId>
             <artifactId>ehcache</artifactId>
         </dependency>
+        <!--一个工具类库,不用自己造轮子了!!!-->
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.2.5</version>
+        </dependency>
     </dependencies>
 
     <build>

+ 2 - 1
src/main/java/nju/seec/helper/api/bok/BokKnowledgeApi.java

@@ -2,6 +2,7 @@ package nju.seec.helper.api.bok;
 
 import lombok.AllArgsConstructor;
 import lombok.Data;
+import nju.seec.helper.util.Consts;
 import nju.seec.helper.util.RestRequestUtil;
 import nju.seec.helper.util.cache.GuavaCacheUtils;
 import nju.seec.helper.vo.knowledge.BokKnowledgeNodeVO;
@@ -24,7 +25,7 @@ public class BokKnowledgeApi {
     @Value("${bok.knowledgeGetAllUrl}")
     private String knowledgeGetAllUrl;
 
-    private static final String BOK_KNOWLEDGE_CACHE_NAME = "helper_bok_knowledge";
+    private static final String BOK_KNOWLEDGE_CACHE_NAME = Consts.SYS_NAME + "_bok_knowledge";
 
     public BokKnowledgeApi(RestRequestUtil restRequestUtil, GuavaCacheUtils cacheUtils) {
         this.restRequestUtil = restRequestUtil;

+ 10 - 5
src/main/java/nju/seec/helper/api/bok/BokQuestionApi.java

@@ -11,8 +11,9 @@ import nju.seec.helper.dto.question.TrueOrFalseQuestionDTO;
 import nju.seec.helper.enums.ExceptionType;
 import nju.seec.helper.enums.QuestionType;
 import nju.seec.helper.exception.HelperException;
-import nju.seec.helper.util.cache.GuavaCacheUtils;
+import nju.seec.helper.util.Consts;
 import nju.seec.helper.util.RestRequestUtil;
+import nju.seec.helper.util.cache.GuavaCacheUtils;
 import nju.seec.helper.vo.question.BokQuestionVO;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.domain.Page;
@@ -55,12 +56,12 @@ public class BokQuestionApi {
         );
         BokSearchResult result = restRequestUtil.sendGetRequest(tqStemSearchUrl, BokSearchResult.class, urlParams);
 
-        List<BokQuestionVO> bokQuestionVOS = result.getEmbedded().getQuestions();
-        cacheUtils.setAll(BOK_QUESTION_CACHE_NAME, bokQuestionVOS.parallelStream().collect(Collectors.toMap(BokQuestionVO::getId, bokQuestion -> bokQuestion)));
-        return new PageImpl<>(bokQuestionVOS, pageable, result.getPage().getTotalElements());
+        List<BokQuestionVO> bokQuestionVOList = result.getEmbedded().getQuestions();
+        cacheUtils.setAll(BOK_QUESTION_CACHE_NAME, bokQuestionVOList.parallelStream().collect(Collectors.toMap(BokQuestionVO::getId, bokQuestion -> bokQuestion)));
+        return new PageImpl<>(bokQuestionVOList, pageable, result.getPage().getTotalElements());
     }
 
-    private static final String BOK_QUESTION_CACHE_NAME = "helper_bok_question";
+    private static final String BOK_QUESTION_CACHE_NAME = Consts.SYS_NAME + "_bok_question";
 
     @SuppressWarnings({"unchecked", "rawtypes"})
     public List<BokQuestionVO> bokFindByIdIn(final List<String> ids) {
@@ -117,6 +118,10 @@ public class BokQuestionApi {
         restRequestUtil.sendDeleteRequest(tqUrl + "/" + questionId);
     }
 
+    public void starQuestion(String userId, String questionId) {
+
+    }
+
     private BokQuestionVO getQuestion(BaseQuestionDTO baseQuestionDTO) {
         BokQuestionVO bokQuestionVO = new BokQuestionVO();
         bokQuestionVO.setType(baseQuestionDTO.getType());

+ 0 - 22
src/main/java/nju/seec/helper/config/PageableConfig.java

@@ -1,22 +0,0 @@
-package nju.seec.helper.config;
-
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.data.web.config.PageableHandlerMethodArgumentResolverCustomizer;
-
-/**
- * @ClassName PageableConfig
- * @PackageName nju.seec.helper.config
- * @Author SheentXu
- * @Date 2019/12/24
- * @Version 1.0
- * @Description
- **/
-@Configuration
-public class PageableConfig {
-
-    @Bean
-    PageableHandlerMethodArgumentResolverCustomizer pageableResolverCustomizer() {
-        return pageableResolver -> pageableResolver.setOneIndexedParameters(true);
-    }
-}

+ 6 - 0
src/main/java/nju/seec/helper/controller/QuestionController.java

@@ -106,4 +106,10 @@ public class QuestionController {
     public Set<String> getCreatedQuestionIds(LoginUser user) {
         return questionService.getIdsOfCreatedQuestions(user);
     }
+
+    @Auth(roles = UserType.STUDENT, message = "收藏题目")
+    @PostMapping("/{questionId}/star")
+    public void starQuestion(LoginUser user, @PathVariable String questionId) {
+        questionService.starQuestion(user, questionId);
+    }
 }

+ 1 - 1
src/main/java/nju/seec/helper/controller/QuizController.java

@@ -117,7 +117,7 @@ public class QuizController {
      */
     @Auth(roles = {UserType.STUDENT}, message = "提交作答")
     @PostMapping("/{quizId}/student-answer")
-    public QuizStudentAnswerVO submitQuizStudentAnswer(LoginUser user, @PathVariable Long quizId, @RequestBody QuizStudentAnswerDTO quizStudentAnswerDTO) {
+    public QuizStudentAnswerVO submitQuizStudentAnswer(LoginUser user, @PathVariable Long quizId, @Validated @RequestBody QuizStudentAnswerDTO quizStudentAnswerDTO) {
         return quizStudentAnswerService.submitQuizStudentAnswer(user, quizId, quizStudentAnswerDTO);
     }
 

+ 17 - 0
src/main/java/nju/seec/helper/dto/quiz/QuizStudentAnswerDTO.java

@@ -2,8 +2,11 @@ package nju.seec.helper.dto.quiz;
 
 import lombok.Data;
 
+import javax.validation.Valid;
 import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
 import java.io.Serializable;
+import java.time.LocalDateTime;
 import java.util.Map;
 
 /**
@@ -14,4 +17,18 @@ public class QuizStudentAnswerDTO implements Serializable {
     private static final long serialVersionUID = -5846899734313166305L;
     @NotEmpty(message = "回答不能为空")
     private Map<String, Object> answers;
+
+    @Valid
+    private Map<String, AnswerRecordDTO> records;
+
+    @Data
+    public static class AnswerRecordDTO {
+        @NotNull(message = "做题记录缺少做题日期")
+        private LocalDateTime answerAt;
+        /**
+         * 秒数
+         */
+        @NotNull(message = "做题记录缺少时长")
+        private Long answerSeconds;
+    }
 }

+ 3 - 0
src/main/java/nju/seec/helper/entity/CourseFile.java

@@ -2,6 +2,7 @@ package nju.seec.helper.entity;
 
 import lombok.Data;
 import lombok.experimental.Accessors;
+import org.hibernate.annotations.CacheConcurrencyStrategy;
 import org.hibernate.annotations.CreationTimestamp;
 
 import javax.persistence.*;
@@ -14,6 +15,8 @@ import java.time.LocalDateTime;
 @Accessors(chain = true)
 @Entity
 @Table(name = "course_file", uniqueConstraints = {@UniqueConstraint(name = "course_file_name_unique", columnNames = {"course_id", "file_name"})})
+@Cacheable
+@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
 public class CourseFile {
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)

+ 3 - 0
src/main/java/nju/seec/helper/entity/Notice.java

@@ -2,6 +2,7 @@ package nju.seec.helper.entity;
 
 import lombok.Data;
 import lombok.experimental.Accessors;
+import org.hibernate.annotations.CacheConcurrencyStrategy;
 import org.hibernate.annotations.CreationTimestamp;
 import org.hibernate.annotations.UpdateTimestamp;
 
@@ -15,6 +16,8 @@ import java.time.LocalDateTime;
 @Accessors(chain = true)
 @Entity
 @Table(name = "notice")
+@Cacheable
+@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
 public class Notice {
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)

+ 8 - 0
src/main/java/nju/seec/helper/service/QuestionService.java

@@ -95,4 +95,12 @@ public interface QuestionService {
      * @return
      */
     Set<String> getIdsOfCreatedQuestions(LoginUser user);
+
+    /**
+     * 收藏题目
+     *
+     * @param user
+     * @param questionId
+     */
+    void starQuestion(LoginUser user, String questionId);
 }

+ 2 - 2
src/main/java/nju/seec/helper/service/impl/AdminServiceImpl.java

@@ -1,5 +1,6 @@
 package nju.seec.helper.service.impl;
 
+import cn.hutool.crypto.SecureUtil;
 import nju.seec.helper.aspect.auth.LoginUser;
 import nju.seec.helper.dao.AdminDAO;
 import nju.seec.helper.dao.UserDAO;
@@ -9,7 +10,6 @@ import nju.seec.helper.enums.UserState;
 import nju.seec.helper.enums.UserType;
 import nju.seec.helper.exception.HelperException;
 import nju.seec.helper.service.AdminService;
-import nju.seec.helper.util.EncryptUtils;
 import nju.seec.helper.util.StringUtils;
 import nju.seec.helper.vo.AdminVO;
 import nju.seec.helper.vo.UserVO;
@@ -35,7 +35,7 @@ public class AdminServiceImpl implements AdminService {
     @Transactional(readOnly = true)
     @Override
     public AdminVO getAdminByUsernameAndPassword(String username, String password) {
-        return adminDAO.findByUsernameAndPassword(username, EncryptUtils.encode(password))
+        return adminDAO.findByUsernameAndPassword(username, SecureUtil.sha256(password))
                 .map(AdminVO::new)
                 .orElseThrow(() -> HelperException.of(ExceptionType.NOT_FOUND, "用户名密码错误"));
     }

+ 7 - 2
src/main/java/nju/seec/helper/service/impl/QuestionServiceImpl.java

@@ -1,5 +1,6 @@
 package nju.seec.helper.service.impl;
 
+import cn.hutool.core.util.IdUtil;
 import nju.seec.helper.api.bok.BokQuestionApi;
 import nju.seec.helper.aspect.auth.LoginUser;
 import nju.seec.helper.dao.QuestionRecordDAO;
@@ -24,7 +25,6 @@ import org.springframework.transaction.annotation.Transactional;
 
 import java.util.List;
 import java.util.Set;
-import java.util.UUID;
 import java.util.stream.Collectors;
 
 /**
@@ -87,7 +87,7 @@ public class QuestionServiceImpl implements QuestionService {
         String questionId;
         do {
             // 保证不产生重复QuestionId
-            questionId = UUID.randomUUID().toString().replaceAll("-", "");
+            questionId = IdUtil.fastSimpleUUID();
         } while (questionRecordDAO.existsByQuestionId(questionId));
 
         BokQuestionVO bokQuestionVO = bokQuestionApi.createQuestion(questionId, baseQuestionDTO);
@@ -136,4 +136,9 @@ public class QuestionServiceImpl implements QuestionService {
     public Set<String> getIdsOfCreatedQuestions(LoginUser user) {
         return questionRecordDAO.findQuestionIdsByTeacher(userDAO.findUserById(user.getId()));
     }
+
+    @Override
+    public void starQuestion(LoginUser user, String questionId) {
+        bokQuestionApi.starQuestion(String.valueOf(user.getId()), questionId);
+    }
 }

+ 16 - 6
src/main/java/nju/seec/helper/service/impl/SlideServiceImpl.java

@@ -1,7 +1,7 @@
 package nju.seec.helper.service.impl;
 
+import cn.hutool.core.text.StrBuilder;
 import com.google.common.collect.ImmutableSet;
-import com.google.common.io.Files;
 import lombok.SneakyThrows;
 import nju.seec.helper.aspect.auth.LoginUser;
 import nju.seec.helper.dao.ChooseDAO;
@@ -21,16 +21,17 @@ import nju.seec.helper.service.CourseService;
 import nju.seec.helper.service.MessageService;
 import nju.seec.helper.service.QuizService;
 import nju.seec.helper.service.SlideService;
-import nju.seec.helper.util.oss.OssObjectUrlUtils;
-import nju.seec.helper.util.oss.OssUtils;
 import nju.seec.helper.util.file.FileInfo;
 import nju.seec.helper.util.file.FileUtils;
+import nju.seec.helper.util.oss.OssObjectUrlUtils;
+import nju.seec.helper.util.oss.OssUtils;
 import nju.seec.helper.vo.SlideVO;
 import org.springframework.dao.DataIntegrityViolationException;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.io.File;
@@ -115,7 +116,7 @@ public class SlideServiceImpl implements SlideService {
         try {
             slide.setName(slideDTO.getName());
             String oldObjectName = slide.getObjectName();
-            String newObjectName = getObjectName(slide.getId(), slide.getName(), Files.getFileExtension(oldObjectName));
+            String newObjectName = getObjectName(slide.getId(), slide.getName(), StringUtils.getFilenameExtension(oldObjectName));
             slide.setObjectName(newObjectName);
             slide = slideDAO.save(slide);
 
@@ -192,11 +193,20 @@ public class SlideServiceImpl implements SlideService {
 
     @SneakyThrows
     private FileInfo getFileInfo(MultipartFile file) {
-        return FileUtils.getFileInfo(file);
+        return FileUtils.getFileInfo(file.getInputStream());
     }
 
     private String getObjectName(Long slideId, String slideName, String extension) {
-        return SLIDE_STORE_DIR + File.separator + slideId + File.separator + slideName + "." + extension;
+        return StrBuilder
+                .create()
+                .append(SLIDE_STORE_DIR)
+                .append(File.separator)
+                .append(slideId)
+                .append(File.separator)
+                .append(slideName)
+                .append(".")
+                .append(extension)
+                .toStringAndReset();
     }
 
     @Transactional(readOnly = true)

+ 4 - 4
src/main/java/nju/seec/helper/service/impl/UserServiceImpl.java

@@ -1,5 +1,6 @@
 package nju.seec.helper.service.impl;
 
+import cn.hutool.crypto.SecureUtil;
 import nju.seec.helper.aspect.auth.LoginUser;
 import nju.seec.helper.dao.UserDAO;
 import nju.seec.helper.dto.user.ResetPasswordDTO;
@@ -11,7 +12,6 @@ import nju.seec.helper.enums.UserType;
 import nju.seec.helper.exception.HelperException;
 import nju.seec.helper.service.UserService;
 import nju.seec.helper.util.Consts;
-import nju.seec.helper.util.EncryptUtils;
 import nju.seec.helper.util.cache.RedisCacheUtils;
 import nju.seec.helper.vo.UserVO;
 import org.springframework.stereotype.Service;
@@ -50,7 +50,7 @@ public class UserServiceImpl implements UserService {
                 .setName(userDTO.getName())
                 .setEmail(userDTO.getEmail())
                 .setPhone(userDTO.getPhone())
-                .setPassword(EncryptUtils.encode(userDTO.getPassword()))
+                .setPassword(SecureUtil.sha256(userDTO.getPassword()))
                 .setType(userDTO.getType())
                 .setState(userDTO.getType() == UserType.TEACHER ? UserState.CHECKING : UserState.NORMAL));
 
@@ -78,7 +78,7 @@ public class UserServiceImpl implements UserService {
             throw HelperException.of(ExceptionType.NOT_FOUND, "邮箱或验证码错误");
         }
 
-        user.setPassword(EncryptUtils.encode(resetPasswordDTO.getPassword()));
+        user.setPassword(SecureUtil.sha256(resetPasswordDTO.getPassword()));
         userDAO.save(user);
         cacheUtils.remove(Consts.EMAIL_CACHE_NAME, resetPasswordDTO.getUsername());
     }
@@ -87,7 +87,7 @@ public class UserServiceImpl implements UserService {
     @Override
     public UserVO getUserByEmailAndPassword(String email, String password) {
         return userDAO
-                .findByEmailAndPassword(email, EncryptUtils.encode(password))
+                .findByEmailAndPassword(email, SecureUtil.sha256(password))
                 .map(UserVO::new)
                 .orElseThrow(() -> HelperException.of(ExceptionType.NOT_FOUND, "邮箱或密码错误"));
     }

+ 0 - 25
src/main/java/nju/seec/helper/util/EncryptUtils.java

@@ -1,25 +0,0 @@
-package nju.seec.helper.util;
-
-import lombok.SneakyThrows;
-import lombok.experimental.UtilityClass;
-import org.apache.commons.codec.binary.Hex;
-
-import java.security.MessageDigest;
-
-/**
- * @author cst
- */
-@UtilityClass
-public class EncryptUtils {
-    private static final String ALGORITHM = "SHA-256";
-
-    /**
-     * 加密
-     */
-    @SneakyThrows
-    public String encode(String string) {
-        MessageDigest messageDigest = MessageDigest.getInstance(ALGORITHM);
-        byte[] hash = messageDigest.digest(string.getBytes());
-        return Hex.encodeHexString(hash);
-    }
-}

+ 7 - 2
src/main/java/nju/seec/helper/util/JsonUtils.java

@@ -2,18 +2,23 @@ package nju.seec.helper.util;
 
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
+import com.google.gson.JsonPrimitive;
+import com.google.gson.JsonSerializer;
 import com.google.gson.reflect.TypeToken;
 import lombok.experimental.UtilityClass;
-import nju.seec.helper.util.serializer.LocalDateTimeSerializer;
 
 import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
 
 /**
  * @author cst
  */
 @UtilityClass
 public class JsonUtils {
-    private static final Gson GSON = new GsonBuilder().setPrettyPrinting().registerTypeAdapter(LocalDateTime.class, new LocalDateTimeSerializer()).create();
+    private static final Gson GSON = new GsonBuilder()
+            .setPrettyPrinting()
+            .registerTypeAdapter(LocalDateTime.class, (JsonSerializer<LocalDateTime>) (localDateTime, type, jsonSerializationContext) -> new JsonPrimitive(localDateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)))
+            .create();
 
     public String toJson(Object o) {
         return GSON.toJson(o);

+ 6 - 5
src/main/java/nju/seec/helper/util/cache/GuavaCacheUtils.java

@@ -23,11 +23,12 @@ public class GuavaCacheUtils {
     public GuavaCacheUtils(@Value("${guavaCache.maximumSize}") Long maximumSize,
                            @Value("${guavaCache.expireAfterAccessInSeconds}") Long expireAfterAccessInSeconds,
                            @Value("${guavaCache.expireAfterWriteInSeconds}") Long expireAfterWriteInSeconds) {
-        CacheBuilder<Object, Object> builder = CacheBuilder.newBuilder();
-        builder.maximumSize(maximumSize);
-        builder.expireAfterAccess(expireAfterAccessInSeconds, TimeUnit.SECONDS);
-        builder.expireAfterWrite(expireAfterWriteInSeconds, TimeUnit.SECONDS);
-        cache = builder.build();
+        cache = CacheBuilder
+                .newBuilder()
+                .maximumSize(maximumSize)
+                .expireAfterAccess(expireAfterAccessInSeconds, TimeUnit.SECONDS)
+                .expireAfterWrite(expireAfterWriteInSeconds, TimeUnit.SECONDS)
+                .build();
     }
 
     public void set(String cacheName, String key, Object value) {

+ 17 - 16
src/main/java/nju/seec/helper/util/file/FileUtils.java

@@ -1,5 +1,6 @@
 package nju.seec.helper.util.file;
 
+import cn.hutool.core.io.FileTypeUtil;
 import com.google.common.collect.ImmutableMap;
 import lombok.SneakyThrows;
 import lombok.experimental.UtilityClass;
@@ -7,11 +8,10 @@ import nju.seec.helper.enums.ExceptionType;
 import nju.seec.helper.exception.HelperException;
 import org.apache.pdfbox.pdmodel.PDDocument;
 import org.apache.pdfbox.text.PDFTextStripper;
-import org.apache.poi.hslf.usermodel.HSLFSlideShow;
-import org.apache.poi.sl.extractor.SlideShowExtractor;
-import org.apache.poi.xslf.usermodel.XMLSlideShow;
-import org.springframework.web.multipart.MultipartFile;
+import org.apache.poi.util.IOUtils;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.Map;
@@ -23,27 +23,28 @@ import java.util.Optional;
 @UtilityClass
 public class FileUtils {
     private static final Map<String, FileInfoParser> FILE_INFO_PARSER_MAP = ImmutableMap.of(
-            "application/pdf", file -> FileInfo.of(PDDocument.load(file.getInputStream()).getNumberOfPages(), "pdf")
-            , "application/vnd.ms-powerpoint", file -> FileInfo.of(new HSLFSlideShow(file.getInputStream()).getSlides().size(), "ppt")
-            , "application/vnd.openxmlformats-officedocument.presentationml.presentation", file -> FileInfo.of(new XMLSlideShow(file.getInputStream()).getSlides().size(), "pptx")
+            "pdf", inputStream -> {
+                System.out.println(inputStream);
+                return FileInfo.of(PDDocument.load(inputStream).getNumberOfPages(), "pdf");
+            }
     );
 
     private static final Map<String, FileContentParser> FILE_CONTENT_PARSER_MAP = ImmutableMap.of(
             "pdf", inputStream -> new PDFTextStripper().getText(PDDocument.load(inputStream))
-            , "ppt", inputStream -> new SlideShowExtractor<>(new HSLFSlideShow(inputStream)).getText()
-            , "pptx", inputStream -> new SlideShowExtractor<>(new XMLSlideShow(inputStream)).getText()
     );
 
     @SneakyThrows
-    public FileInfo getFileInfo(MultipartFile file) {
-        return Optional.ofNullable(FILE_INFO_PARSER_MAP.get(file.getContentType()))
+    public FileInfo getFileInfo(InputStream inputStream) {
+        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+        IOUtils.copy(inputStream, byteArrayOutputStream);
+        return Optional.ofNullable(FILE_INFO_PARSER_MAP.get(FileTypeUtil.getType(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()))))
                 .orElseThrow(() -> HelperException.of(ExceptionType.FORBIDDEN, "不支持的文件类型"))
-                .parse(file);
+                .parse(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()));
     }
 
     @SneakyThrows
-    public String getFileContent(String extension, InputStream inputStream) {
-        return Optional.ofNullable(FILE_CONTENT_PARSER_MAP.get(extension))
+    public String getFileContent(InputStream inputStream) {
+        return Optional.ofNullable(FILE_CONTENT_PARSER_MAP.get(FileTypeUtil.getType(inputStream)))
                 .orElseThrow(() -> HelperException.of(ExceptionType.FORBIDDEN, "不支持的文件类型"))
                 .parse(inputStream);
     }
@@ -53,11 +54,11 @@ public class FileUtils {
         /**
          * 解析文件信息
          *
-         * @param file
+         * @param inputStream
          * @return
          * @throws IOException
          */
-        FileInfo parse(MultipartFile file) throws IOException;
+        FileInfo parse(InputStream inputStream) throws IOException;
     }
 
     @FunctionalInterface

+ 3 - 4
src/main/java/nju/seec/helper/util/oss/OssObjectUrlUtils.java

@@ -23,11 +23,10 @@ public class OssObjectUrlUtils {
 
     public String getUrl(String objectName) {
         String url = cacheUtils.get(OSS_OBJECT_URL_NAME, objectName);
-        if (url != null) {
-            return url;
+        if (url == null) {
+            url = ossUtils.getUrl(objectName, OSS_OBJECT_URL_LIVING_SECONDS);
+            cacheUtils.set(OSS_OBJECT_URL_NAME, objectName, url, OSS_OBJECT_URL_LIVING_SECONDS, TimeUnit.SECONDS);
         }
-        url = ossUtils.getUrl(objectName, OSS_OBJECT_URL_LIVING_SECONDS);
-        cacheUtils.set(OSS_OBJECT_URL_NAME, objectName, url, OSS_OBJECT_URL_LIVING_SECONDS, TimeUnit.SECONDS);
         return url;
     }
 }

+ 0 - 21
src/main/java/nju/seec/helper/util/serializer/LocalDateTimeSerializer.java

@@ -1,21 +0,0 @@
-package nju.seec.helper.util.serializer;
-
-import com.google.gson.JsonElement;
-import com.google.gson.JsonPrimitive;
-import com.google.gson.JsonSerializationContext;
-import com.google.gson.JsonSerializer;
-
-import java.lang.reflect.Type;
-import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
-
-/**
- * @author cst
- */
-public class LocalDateTimeSerializer implements JsonSerializer<LocalDateTime> {
-
-    @Override
-    public JsonElement serialize(LocalDateTime localDateTime, Type type, JsonSerializationContext jsonSerializationContext) {
-        return new JsonPrimitive(localDateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
-    }
-}

+ 2 - 1
src/main/java/nju/seec/helper/vo/question/TrueOrFalseQuestionVO.java

@@ -1,5 +1,6 @@
 package nju.seec.helper.vo.question;
 
+import cn.hutool.core.convert.Convert;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NonNull;
@@ -18,7 +19,7 @@ public class TrueOrFalseQuestionVO extends BaseQuestionVO {
 
     @Override
     public boolean pass(Object answer) {
-        return this.answer.equals(Boolean.valueOf(String.valueOf(answer)));
+        return this.answer.equals(Convert.toBool(answer));
     }
 
     public TrueOrFalseQuestionVO(@NonNull BokQuestionVO bokQuestionVO, boolean withAnswer) {

+ 4 - 0
src/main/resources/application-deploy.yml

@@ -21,6 +21,10 @@ spring:
     redis:
       repositories:
         enabled: false
+    web:
+      pageable:
+        max-page-size: 1000
+        one-indexed-parameters: true
   mail:
     host: smtp.exmail.qq.com
     username: noreply@seecoder.cn

+ 4 - 0
src/main/resources/application-dev.yml

@@ -21,6 +21,10 @@ spring:
     redis:
       repositories:
         enabled: false
+    web:
+      pageable:
+        max-page-size: 1000
+        one-indexed-parameters: true
   mail:
     host: smtp.exmail.qq.com
     username: noreply@seecoder.cn