Преглед на файлове

Merge branch 'rongrunxiang/judge' of rongrunxiang/OnlineJudge into master

rongrunxiang преди 1 година
родител
ревизия
5762020f3d
променени са 42 файла, в които са добавени 1397 реда и са изтрити 86 реда
  1. 7 2
      pom.xml
  2. 29 0
      src/main/java/com/example/onlinejudge/common/BaseResponse.java
  3. 16 0
      src/main/java/com/example/onlinejudge/common/DeleteRequest.java
  4. 37 0
      src/main/java/com/example/onlinejudge/common/ErrorCode.java
  5. 28 0
      src/main/java/com/example/onlinejudge/common/PageRequest.java
  6. 46 0
      src/main/java/com/example/onlinejudge/common/ResultUtils.java
  7. 14 0
      src/main/java/com/example/onlinejudge/constant/CommonConstant.java
  8. 2 1
      src/main/java/com/example/onlinejudge/controller/JudgeController.java
  9. 244 0
      src/main/java/com/example/onlinejudge/controller/QuestionController.java
  10. 82 0
      src/main/java/com/example/onlinejudge/controller/QuestionSubmitController.java
  11. 27 0
      src/main/java/com/example/onlinejudge/exception/BusinessException.java
  12. 39 0
      src/main/java/com/example/onlinejudge/exception/ThrowUtils.java
  13. 30 0
      src/main/java/com/example/onlinejudge/judge/JudgeManager.java
  14. 10 0
      src/main/java/com/example/onlinejudge/judge/JudgeService.java
  15. 21 0
      src/main/java/com/example/onlinejudge/judge/JudgeServiceImpl.java
  16. 8 0
      src/main/java/com/example/onlinejudge/judge/codesandbox/CodeSandbox.java
  17. 4 0
      src/main/java/com/example/onlinejudge/judge/codesandbox/CodeSandboxFactory.java
  18. 24 0
      src/main/java/com/example/onlinejudge/judge/codesandbox/CodeSandboxProxy.java
  19. 28 0
      src/main/java/com/example/onlinejudge/judge/codesandbox/impl/ExampleCodeSandbox.java
  20. 13 0
      src/main/java/com/example/onlinejudge/judge/codesandbox/impl/RemoteCodeSandbox.java
  21. 14 0
      src/main/java/com/example/onlinejudge/judge/codesandbox/impl/ThirdPartyCodeSandbox.java
  22. 21 0
      src/main/java/com/example/onlinejudge/judge/codesandbox/model/ExecuteCodeRequest.java
  23. 23 0
      src/main/java/com/example/onlinejudge/judge/codesandbox/model/ExecuteCodeResponse.java
  24. 22 0
      src/main/java/com/example/onlinejudge/judge/codesandbox/model/JudgeInfo.java
  25. 59 0
      src/main/java/com/example/onlinejudge/judge/strategy/DefaultJudgeStrategy.java
  26. 61 0
      src/main/java/com/example/onlinejudge/judge/strategy/JavaLanguageJudgeStrategy.java
  27. 25 0
      src/main/java/com/example/onlinejudge/judge/strategy/JudgeContext.java
  28. 10 0
      src/main/java/com/example/onlinejudge/judge/strategy/JudgeStrategy.java
  29. 8 0
      src/main/java/com/example/onlinejudge/mapper/QuestionMapper.java
  30. 12 2
      src/main/java/com/example/onlinejudge/mapper/QuestionSubmitMapper.java
  31. 42 0
      src/main/java/com/example/onlinejudge/model/dto/question/QuestionAddRequest.java
  32. 42 0
      src/main/java/com/example/onlinejudge/model/dto/question/QuestionEditRequest.java
  33. 45 0
      src/main/java/com/example/onlinejudge/model/dto/question/QuestionQueryRequest.java
  34. 47 0
      src/main/java/com/example/onlinejudge/model/dto/question/QuestionUpdateRequest.java
  35. 20 6
      src/main/java/com/example/onlinejudge/model/dto/questionSubmit/QuestionSubmitQueryRequest.java
  36. 0 2
      src/main/java/com/example/onlinejudge/model/entity/SubmitCode.java
  37. 38 13
      src/main/java/com/example/onlinejudge/service/QuestionService.java
  38. 49 0
      src/main/java/com/example/onlinejudge/service/QuestionSubmitService.java
  39. 2 0
      src/main/java/com/example/onlinejudge/service/UserService.java
  40. 139 60
      src/main/java/com/example/onlinejudge/service/impl/QuestionServiceImpl.java
  41. 4 0
      src/main/java/com/example/onlinejudge/service/impl/QuestionSubmitServiceImpl.java
  42. 5 0
      src/main/java/com/example/onlinejudge/service/impl/UserServiceImpl.java

+ 7 - 2
pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-parent</artifactId>
-        <version>2.2.2.RELEASE</version>
+        <version>2.7.2</version>
         <relativePath/> <!-- lookup parent from repository -->
     </parent>
     <groupId>com.example</groupId>
@@ -14,7 +14,7 @@
     <name>OnlineJudge</name>
     <description>OnlineJudge</description>
     <properties>
-        <java.version>8</java.version>
+        <java.version>1.8</java.version>
     </properties>
     <dependencies>
         <dependency>
@@ -53,6 +53,11 @@
             <artifactId>commons-lang3</artifactId>
         </dependency>
         <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+            <version>2.9.1</version>
+        </dependency>
+        <dependency>
             <groupId>com.baomidou</groupId>
             <artifactId>mybatis-plus-boot-starter</artifactId>
             <version>3.5.2</version>

+ 29 - 0
src/main/java/com/example/onlinejudge/common/BaseResponse.java

@@ -0,0 +1,29 @@
+package com.example.onlinejudge.common;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class BaseResponse<T> implements Serializable {
+
+    private int code;
+
+    private T data;
+
+    private String message;
+
+    public BaseResponse(int code, T data, String message) {
+        this.code = code;
+        this.data = data;
+        this.message = message;
+    }
+
+    public BaseResponse(int code, T data) {
+        this(code, data, "");
+    }
+
+    public BaseResponse(ErrorCode errorCode) {
+        this(errorCode.getCode(), null, errorCode.getMessage());
+    }
+}

+ 16 - 0
src/main/java/com/example/onlinejudge/common/DeleteRequest.java

@@ -0,0 +1,16 @@
+package com.example.onlinejudge.common;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class DeleteRequest implements Serializable {
+
+    /**
+     * id
+     */
+    private Long id;
+
+    private static final long serialVersionUID = 1L;
+}

+ 37 - 0
src/main/java/com/example/onlinejudge/common/ErrorCode.java

@@ -0,0 +1,37 @@
+package com.example.onlinejudge.common;
+
+public enum ErrorCode {
+
+    SUCCESS(0, "ok"),
+    PARAMS_ERROR(40000, "请求参数错误"),
+    NOT_LOGIN_ERROR(40100, "未登录"),
+    NO_AUTH_ERROR(40101, "无权限"),
+    NOT_FOUND_ERROR(40400, "请求数据不存在"),
+    FORBIDDEN_ERROR(40300, "禁止访问"),
+    SYSTEM_ERROR(50000, "系统内部异常"),
+    OPERATION_ERROR(50001, "操作失败");
+
+    /**
+     * 状态码
+     */
+    private final int code;
+
+    /**
+     * 信息
+     */
+    private final String message;
+
+    ErrorCode(int code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+}

+ 28 - 0
src/main/java/com/example/onlinejudge/common/PageRequest.java

@@ -0,0 +1,28 @@
+package com.example.onlinejudge.common;
+
+import com.example.onlinejudge.constant.CommonConstant;
+import lombok.Data;
+
+@Data
+public class PageRequest {
+
+    /**
+     * 当前页号
+     */
+    private long current = 1;
+
+    /**
+     * 页面大小
+     */
+    private long pageSize = 10;
+
+    /**
+     * 排序字段
+     */
+    private String sortField;
+
+    /**
+     * 排序顺序(默认升序)
+     */
+    private String sortOrder = CommonConstant.SORT_ORDER_ASC;
+}

+ 46 - 0
src/main/java/com/example/onlinejudge/common/ResultUtils.java

@@ -0,0 +1,46 @@
+package com.example.onlinejudge.common;
+
+public class ResultUtils {
+
+    /**
+     * 成功
+     *
+     * @param data
+     * @param <T>
+     * @return
+     */
+    public static <T> BaseResponse<T> success(T data) {
+        return new BaseResponse<>(0, data, "ok");
+    }
+
+    /**
+     * 失败
+     *
+     * @param errorCode
+     * @return
+     */
+    public static BaseResponse error(ErrorCode errorCode) {
+        return new BaseResponse<>(errorCode);
+    }
+
+    /**
+     * 失败
+     *
+     * @param code
+     * @param message
+     * @return
+     */
+    public static BaseResponse error(int code, String message) {
+        return new BaseResponse(code, null, message);
+    }
+
+    /**
+     * 失败
+     *
+     * @param errorCode
+     * @return
+     */
+    public static BaseResponse error(ErrorCode errorCode, String message) {
+        return new BaseResponse(errorCode.getCode(), null, message);
+    }
+}

+ 14 - 0
src/main/java/com/example/onlinejudge/constant/CommonConstant.java

@@ -0,0 +1,14 @@
+package com.example.onlinejudge.constant;
+
+public interface CommonConstant {
+
+    /**
+     * 升序
+     */
+    String SORT_ORDER_ASC = "ascend";
+
+    /**
+     * 降序
+     */
+    String SORT_ORDER_DESC = " descend";
+}

+ 2 - 1
src/main/java/com/example/onlinejudge/controller/JudgeController.java

@@ -32,6 +32,7 @@ public class JudgeController {
                              @RequestParam("language")String language,
                              @RequestParam(defaultValue = "", value = "userCases") String userCases,
                              @RequestParam(value = "judgeMode") Integer judgeMode) {
-        return questionService.receiveCode(Long.parseLong(questionID), code, language, userCases, judgeMode);
+        return null;
+//                questionService.receiveCode(Long.parseLong(questionID), code, language, userCases, judgeMode);
     }
 }

+ 244 - 0
src/main/java/com/example/onlinejudge/controller/QuestionController.java

@@ -0,0 +1,244 @@
+package com.example.onlinejudge.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.example.onlinejudge.common.BaseResponse;
+import com.example.onlinejudge.common.DeleteRequest;
+import com.example.onlinejudge.common.ErrorCode;
+import com.example.onlinejudge.common.ResultUtils;
+import com.example.onlinejudge.exception.BusinessException;
+import com.example.onlinejudge.exception.ThrowUtils;
+import com.example.onlinejudge.model.VO.QuestionVO;
+import com.example.onlinejudge.model.dto.question.*;
+import com.example.onlinejudge.model.entity.Question;
+import com.example.onlinejudge.model.entity.User;
+import com.example.onlinejudge.service.QuestionService;
+import com.example.onlinejudge.service.UserService;
+import com.google.gson.Gson;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+
+@RestController
+@RequestMapping("/question")
+@Slf4j
+public class QuestionController {
+
+    @Resource
+    private QuestionService questionService;
+
+    @Resource
+    private UserService userService;
+
+    private final static Gson GSON = new Gson();
+
+    // region 增删改查
+
+    /**
+     * 创建
+     *
+     * @param questionAddRequest
+     * @param request
+     * @return
+     */
+    @PostMapping("/add")
+    public BaseResponse<Long> addQuestion(@RequestBody QuestionAddRequest questionAddRequest, HttpServletRequest request) {
+        if (questionAddRequest == null) {
+            throw new BusinessException(ErrorCode.PARAMS_ERROR);
+        }
+        Question question = new Question();
+        BeanUtils.copyProperties(questionAddRequest, question);
+        List<String> tags = questionAddRequest.getTags();
+        if (tags != null) {
+            question.setTags(GSON.toJson(tags));
+        }
+        List<JudgeCase> judgeCase = questionAddRequest.getJudgeCase();
+        if (judgeCase != null) {
+            question.setJudgeCase(GSON.toJson(judgeCase));
+        }
+        JudgeConfig judgeConfig = questionAddRequest.getJudgeConfig();
+        if (judgeConfig != null) {
+            question.setJudgeConfig(GSON.toJson(judgeConfig));
+        }
+        questionService.validQuestion(question, true);
+//        User loginUser = userService.getLoginUser(request);
+//        question.setUserId(loginUser.getId());
+        boolean result = questionService.save(question);
+        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
+        long newQuestionId = question.getId();
+        return ResultUtils.success(newQuestionId);
+    }
+
+    /**
+     * 删除
+     *
+     * @param deleteRequest
+     * @param request
+     * @return
+     */
+    @PostMapping("/delete")
+    public BaseResponse<Boolean> deleteQuestion(@RequestBody DeleteRequest deleteRequest, HttpServletRequest request) {
+        if (deleteRequest == null || deleteRequest.getId() <= 0) {
+            throw new BusinessException(ErrorCode.PARAMS_ERROR);
+        }
+        long id = deleteRequest.getId();
+        // 判断是否存在
+        Question oldQuestion = questionService.getById(id);
+        ThrowUtils.throwIf(oldQuestion == null, ErrorCode.NOT_FOUND_ERROR);
+        // 仅本人或管理员可删除
+        if (false) {
+            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
+        }
+        boolean b = questionService.removeById(id);
+        return ResultUtils.success(b);
+    }
+
+
+    /**
+     * 根据 id 获取
+     *
+     * @param id
+     * @return
+     */
+    @GetMapping("/get")
+    public BaseResponse<Question> getQuestionById(long id, HttpServletRequest request) {
+        if (id <= 0) {
+            throw new BusinessException(ErrorCode.PARAMS_ERROR);
+        }
+        Question question = questionService.getById(id);
+        if (question == null) {
+            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
+        }
+//        User loginUser = userService.getLoginUser(request);
+//        // 不是本人或管理员,不能直接获取所有信息
+//        if (!question.getUserId().equals(loginUser.getId()) && !userService.isAdmin(loginUser)) {
+//            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
+//        }
+        return ResultUtils.success(question);
+    }
+
+    /**
+     * 根据 id 获取(脱敏)
+     *
+     * @param id
+     * @return
+     */
+    @GetMapping("/get/vo")
+    public BaseResponse<QuestionVO> getQuestionVOById(long id, HttpServletRequest request) {
+        if (id <= 0) {
+            throw new BusinessException(ErrorCode.PARAMS_ERROR);
+        }
+        Question question = questionService.getById(id);
+        if (question == null) {
+            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
+        }
+        return ResultUtils.success(questionService.getQuestionVO(question, request));
+    }
+
+    /**
+     * 分页获取列表(封装类)
+     *
+     * @param questionQueryRequest
+     * @param request
+     * @return
+     */
+    @PostMapping("/list/page/vo")
+    public BaseResponse<Page<QuestionVO>> listQuestionVOByPage(@RequestBody QuestionQueryRequest questionQueryRequest,
+                                                               HttpServletRequest request) {
+        long current = questionQueryRequest.getCurrent();
+        long size = questionQueryRequest.getPageSize();
+        // 限制爬虫
+        ThrowUtils.throwIf(size > 20, ErrorCode.PARAMS_ERROR);
+        Page<Question> questionPage = questionService.page(new Page<>(current, size),
+                questionService.getQueryWrapper(questionQueryRequest));
+        return ResultUtils.success(questionService.getQuestionVOPage(questionPage, request));
+    }
+
+    /**
+     * 分页获取当前用户创建的资源列表
+     *
+     * @param questionQueryRequest
+     * @param request
+     * @return
+     */
+    @PostMapping("/my/list/page/vo")
+    public BaseResponse<Page<QuestionVO>> listMyQuestionVOByPage(@RequestBody QuestionQueryRequest questionQueryRequest,
+                                                                 HttpServletRequest request) {
+        if (questionQueryRequest == null) {
+            throw new BusinessException(ErrorCode.PARAMS_ERROR);
+        }
+//        User loginUser = userService.getLoginUser(request);
+//        questionQueryRequest.setUserId(loginUser.getId());
+        long current = questionQueryRequest.getCurrent();
+        long size = questionQueryRequest.getPageSize();
+        // 限制爬虫
+        ThrowUtils.throwIf(size > 20, ErrorCode.PARAMS_ERROR);
+        Page<Question> questionPage = questionService.page(new Page<>(current, size),
+                questionService.getQueryWrapper(questionQueryRequest));
+        return ResultUtils.success(questionService.getQuestionVOPage(questionPage, request));
+    }
+
+    /**
+     * 分页获取题目列表(仅管理员)
+     *
+     * @param questionQueryRequest
+     * @param request
+     * @return
+     */
+    @PostMapping("/list/page")
+    public BaseResponse<Page<Question>> listQuestionByPage(@RequestBody QuestionQueryRequest questionQueryRequest,
+                                                           HttpServletRequest request) {
+        long current = questionQueryRequest.getCurrent();
+        long size = questionQueryRequest.getPageSize();
+        Page<Question> questionPage = questionService.page(new Page<>(current, size),
+                questionService.getQueryWrapper(questionQueryRequest));
+        return ResultUtils.success(questionPage);
+    }
+
+    // endregion
+
+    /**
+     * 编辑(用户)
+     *
+     * @param questionEditRequest
+     * @param request
+     * @return
+     */
+//    @PostMapping("/edit")
+//    public BaseResponse<Boolean> editQuestion(@RequestBody QuestionEditRequest questionEditRequest, HttpServletRequest request) {
+//        if (questionEditRequest == null || questionEditRequest.getId() <= 0) {
+//            throw new BusinessException(ErrorCode.PARAMS_ERROR);
+//        }
+//        Question question = new Question();
+//        BeanUtils.copyProperties(questionEditRequest, question);
+//        List<String> tags = questionEditRequest.getTags();
+//        if (tags != null) {
+//            question.setTags(GSON.toJson(tags));
+//        }
+//        List<JudgeCase> judgeCase = questionEditRequest.getJudgeCase();
+//        if (judgeCase != null) {
+//            question.setJudgeCase(GSON.toJson(judgeCase));
+//        }
+//        JudgeConfig judgeConfig = questionEditRequest.getJudgeConfig();
+//        if (judgeConfig != null) {
+//            question.setJudgeConfig(GSON.toJson(judgeConfig));
+//        }
+//        // 参数校验
+//        questionService.validQuestion(question, false);
+////        User loginUser = userService.getLoginUser(request);
+////        long id = questionEditRequest.getId();
+//        // 判断是否存在
+////        Question oldQuestion = questionService.getById(id);
+////        ThrowUtils.throwIf(oldQuestion == null, ErrorCode.NOT_FOUND_ERROR);
+//        // 仅本人或管理员可编辑
+////        if (!oldQuestion.getUserId().equals(loginUser.getId()) && !userService.isAdmin(loginUser)) {
+////            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
+////        }
+//        boolean result = questionService.updateById(question);
+//        return ResultUtils.success(result);
+//    }
+
+}

+ 82 - 0
src/main/java/com/example/onlinejudge/controller/QuestionSubmitController.java

@@ -0,0 +1,82 @@
+package com.example.onlinejudge.controller;
+
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.example.onlinejudge.common.BaseResponse;
+import com.example.onlinejudge.common.ResultUtils;
+import com.example.onlinejudge.model.VO.QuestionSubmitVO;
+import com.example.onlinejudge.model.dto.questionSubmit.QuestionSubmitAddRequest;
+import com.example.onlinejudge.model.dto.questionSubmit.QuestionSubmitQueryRequest;
+import com.example.onlinejudge.model.entity.QuestionSubmit;
+import com.example.onlinejudge.model.entity.User;
+import com.example.onlinejudge.model.entity.result.Result;
+import com.example.onlinejudge.model.entity.result.ResultCode;
+import com.example.onlinejudge.service.QuestionSubmitService;
+import com.example.onlinejudge.service.UserService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * 题目提交接口
+ *
+ * @author <a href="https://github.com/liyupi">程序员鱼皮</a>
+ * @from <a href="https://yupi.icu">编程导航知识星球</a>
+ */
+@RestController
+@RequestMapping("/question_submit")
+@Slf4j
+public class QuestionSubmitController {
+
+    @Resource
+    private QuestionSubmitService questionSubmitService;
+
+    @Resource
+    private UserService userService;
+
+    /**
+     * 提交题目
+     *
+     * @param questionSubmitAddRequest
+     * @param request
+     * @return 提交记录的 id
+     */
+    @PostMapping("/")
+    public Result doQuestionSubmit(@RequestBody QuestionSubmitAddRequest questionSubmitAddRequest,
+                                   HttpServletRequest request) {
+        if (questionSubmitAddRequest == null || questionSubmitAddRequest.getQuestionId() <= 0) {
+            return new Result(ResultCode.PARAM_IS_INVALID.getCode(),ResultCode.PARAM_IS_INVALID.getMessage());
+        }
+        // 登录才能点赞
+//        final User loginUser = userService.getLoginUser(request);
+        long questionSubmitId = questionSubmitService.doQuestionSubmit(questionSubmitAddRequest, loginUser);
+        return Result.success(questionSubmitId);
+    }
+
+    /**
+     * 分页获取题目提交列表(除了管理员外,普通用户只能看到非答案、提交代码等公开信息)
+     *
+     * @param questionSubmitQueryRequest
+     * @param request
+     * @return
+     */
+    @PostMapping("/list/page")
+    public BaseResponse<Page<QuestionSubmitVO>> listQuestionSubmitByPage(@RequestBody QuestionSubmitQueryRequest questionSubmitQueryRequest,
+                                                                         HttpServletRequest request) {
+        long current = questionSubmitQueryRequest.getCurrent();
+        long size = questionSubmitQueryRequest.getPageSize();
+        // 从数据库中查询原始的题目提交分页信息
+        Page<QuestionSubmit> questionSubmitPage = questionSubmitService.page(new Page<>(current, size),
+                questionSubmitService.getQueryWrapper(questionSubmitQueryRequest));
+        final User loginUser = userService.getLoginUser(request);
+        // 返回脱敏信息
+        return ResultUtils.success(questionSubmitService.getQuestionSubmitVOPage(questionSubmitPage, loginUser));
+    }
+
+
+}

+ 27 - 0
src/main/java/com/example/onlinejudge/exception/BusinessException.java

@@ -0,0 +1,27 @@
+package com.example.onlinejudge.exception;
+
+
+import com.example.onlinejudge.common.ErrorCode;
+
+public class BusinessException extends RuntimeException {
+    private final int code;
+
+    public BusinessException(int code, String message) {
+        super(message);
+        this.code = code;
+    }
+
+    public BusinessException(ErrorCode errorCode) {
+        super(errorCode.getMessage());
+        this.code = errorCode.getCode();
+    }
+
+    public BusinessException(ErrorCode errorCode, String message) {
+        super(message);
+        this.code = errorCode.getCode();
+    }
+
+    public int getCode() {
+        return code;
+    }
+}

+ 39 - 0
src/main/java/com/example/onlinejudge/exception/ThrowUtils.java

@@ -0,0 +1,39 @@
+package com.example.onlinejudge.exception;
+
+import com.example.onlinejudge.common.ErrorCode;
+
+public class ThrowUtils {
+
+    /**
+     * 条件成立则抛异常
+     *
+     * @param condition
+     * @param runtimeException
+     */
+    public static void throwIf(boolean condition, RuntimeException runtimeException) {
+        if (condition) {
+            throw runtimeException;
+        }
+    }
+
+    /**
+     * 条件成立则抛异常
+     *
+     * @param condition
+     * @param errorCode
+     */
+    public static void throwIf(boolean condition, ErrorCode errorCode) {
+        throwIf(condition, new BusinessException(errorCode));
+    }
+
+    /**
+     * 条件成立则抛异常
+     *
+     * @param condition
+     * @param errorCode
+     * @param message
+     */
+    public static void throwIf(boolean condition, ErrorCode errorCode, String message) {
+        throwIf(condition, new BusinessException(errorCode, message));
+    }
+}

+ 30 - 0
src/main/java/com/example/onlinejudge/judge/JudgeManager.java

@@ -0,0 +1,30 @@
+package com.example.onlinejudge.judge;
+
+import com.example.onlinejudge.judge.strategy.DefaultJudgeStrategy;
+import com.example.onlinejudge.judge.strategy.JavaLanguageJudgeStrategy;
+import com.example.onlinejudge.judge.strategy.JudgeContext;
+import com.example.onlinejudge.judge.strategy.JudgeStrategy;
+import com.example.onlinejudge.model.dto.questionSubmit.JudgeInfo;
+import com.example.onlinejudge.model.entity.QuestionSubmit;
+
+/**
+ * 判题管理(简化调用)
+ */
+public class JudgeManager {
+
+        /**
+        * 执行判题
+        *
+        * @param judgeContext
+        * @return
+        */
+        JudgeInfo doJudge(JudgeContext judgeContext) {
+            QuestionSubmit questionSubmit = judgeContext.getQuestionSubmit();
+            String language = questionSubmit.getLanguage();
+            JudgeStrategy judgeStrategy = new DefaultJudgeStrategy();
+            if ("java".equals(language)) {
+                judgeStrategy = new JavaLanguageJudgeStrategy();
+            }
+            return judgeStrategy.doJudge(judgeContext);
+        }
+}

+ 10 - 0
src/main/java/com/example/onlinejudge/judge/JudgeService.java

@@ -0,0 +1,10 @@
+package com.example.onlinejudge.judge;
+
+import com.example.onlinejudge.model.entity.QuestionSubmit;
+
+/**
+ * 判题服务
+ */
+public interface JudgeService {
+    QuestionSubmit doJudge(long questionSubmitId);
+}

+ 21 - 0
src/main/java/com/example/onlinejudge/judge/JudgeServiceImpl.java

@@ -0,0 +1,21 @@
+package com.example.onlinejudge.judge;
+
+import com.example.onlinejudge.model.entity.QuestionSubmit;
+import com.example.onlinejudge.service.QuestionService;
+import com.example.onlinejudge.service.QuestionSubmitService;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+
+@Service
+public class JudgeServiceImpl implements JudgeService{
+
+    @Resource
+    private QuestionService questionService;
+
+    @Resource
+    QuestionSubmitService questionSubmitService;
+    public QuestionSubmit doJudge(long questionSubmitId) {
+        return null;
+    }
+}

+ 8 - 0
src/main/java/com/example/onlinejudge/judge/codesandbox/CodeSandbox.java

@@ -0,0 +1,8 @@
+package com.example.onlinejudge.judge.codesandbox;
+
+import com.example.onlinejudge.judge.codesandbox.model.ExecuteCodeRequest;
+import com.example.onlinejudge.judge.codesandbox.model.ExecuteCodeResponse;
+
+public interface CodeSandbox {
+    ExecuteCodeResponse executeCode(ExecuteCodeRequest executeCodeRequest);
+}

+ 4 - 0
src/main/java/com/example/onlinejudge/judge/codesandbox/CodeSandboxFactory.java

@@ -0,0 +1,4 @@
+package com.example.onlinejudge.judge.codesandbox;
+
+public class CodeSandboxFactory {
+}

+ 24 - 0
src/main/java/com/example/onlinejudge/judge/codesandbox/CodeSandboxProxy.java

@@ -0,0 +1,24 @@
+package com.example.onlinejudge.judge.codesandbox;
+
+
+import com.example.onlinejudge.judge.codesandbox.model.ExecuteCodeRequest;
+import com.example.onlinejudge.judge.codesandbox.model.ExecuteCodeResponse;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class CodeSandboxProxy implements CodeSandbox{
+
+    private final CodeSandbox codeSandbox;
+
+    public CodeSandboxProxy(CodeSandbox codeSandbox) {
+        this.codeSandbox = codeSandbox;
+    }
+
+    @Override
+    public ExecuteCodeResponse executeCode(ExecuteCodeRequest executeCodeRequest) {
+        log.info("代码沙箱请求信息:" + executeCodeRequest.toString());
+        ExecuteCodeResponse executeCodeResponse = codeSandbox.executeCode(executeCodeRequest);
+        log.info("代码沙箱响应信息:" + executeCodeResponse.toString());
+        return executeCodeResponse;
+    }
+}

+ 28 - 0
src/main/java/com/example/onlinejudge/judge/codesandbox/impl/ExampleCodeSandbox.java

@@ -0,0 +1,28 @@
+package com.example.onlinejudge.judge.codesandbox.impl;
+
+import com.example.onlinejudge.judge.codesandbox.CodeSandbox;
+import com.example.onlinejudge.judge.codesandbox.model.ExecuteCodeRequest;
+import com.example.onlinejudge.judge.codesandbox.model.ExecuteCodeResponse;
+import com.example.onlinejudge.judge.codesandbox.model.JudgeInfo;
+import com.example.onlinejudge.model.enums.JudgeInfoMessageEnum;
+import com.example.onlinejudge.model.enums.QuestionSubmitStatusEnum;
+
+import java.util.List;
+
+public class ExampleCodeSandbox implements CodeSandbox {
+
+    @Override
+    public ExecuteCodeResponse executeCode(ExecuteCodeRequest executeCodeRequest) {
+        List<String> inputList = executeCodeRequest.getInputList();
+        ExecuteCodeResponse executeCodeResponse = new ExecuteCodeResponse();
+        executeCodeResponse.setOutputList(inputList);
+        executeCodeResponse.setMessage("测试执行成功");
+        executeCodeResponse.setStatus(QuestionSubmitStatusEnum.SUCCEED.getValue());
+        JudgeInfo judgeInfo = new JudgeInfo();
+        judgeInfo.setMessage(JudgeInfoMessageEnum.ACCEPTED.getText());
+        judgeInfo.setMemory(100L);
+        judgeInfo.setTime(100L);
+        executeCodeResponse.setJudgeInfo(judgeInfo);
+        return executeCodeResponse;
+    }
+}

+ 13 - 0
src/main/java/com/example/onlinejudge/judge/codesandbox/impl/RemoteCodeSandbox.java

@@ -0,0 +1,13 @@
+package com.example.onlinejudge.judge.codesandbox.impl;
+
+import com.example.onlinejudge.judge.codesandbox.CodeSandbox;
+import com.example.onlinejudge.judge.codesandbox.model.ExecuteCodeRequest;
+import com.example.onlinejudge.judge.codesandbox.model.ExecuteCodeResponse;
+
+public class RemoteCodeSandbox implements CodeSandbox {
+    @Override
+    public ExecuteCodeResponse executeCode(ExecuteCodeRequest executeCodeRequest) {
+        System.out.println("远程代码沙箱");
+        return null;
+    }
+}

+ 14 - 0
src/main/java/com/example/onlinejudge/judge/codesandbox/impl/ThirdPartyCodeSandbox.java

@@ -0,0 +1,14 @@
+package com.example.onlinejudge.judge.codesandbox.impl;
+
+import com.example.onlinejudge.judge.codesandbox.CodeSandbox;
+import com.example.onlinejudge.judge.codesandbox.model.ExecuteCodeRequest;
+import com.example.onlinejudge.judge.codesandbox.model.ExecuteCodeResponse;
+
+public class ThirdPartyCodeSandbox implements CodeSandbox {
+
+    @Override
+    public ExecuteCodeResponse executeCode(ExecuteCodeRequest executeCodeRequest) {
+        System.out.println("第三方代码沙箱");
+        return null;
+    }
+}

+ 21 - 0
src/main/java/com/example/onlinejudge/judge/codesandbox/model/ExecuteCodeRequest.java

@@ -0,0 +1,21 @@
+package com.example.onlinejudge.judge.codesandbox.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class ExecuteCodeRequest {
+
+    private List<String> inputList;
+
+    private String code;
+
+    private String language;
+}

+ 23 - 0
src/main/java/com/example/onlinejudge/judge/codesandbox/model/ExecuteCodeResponse.java

@@ -0,0 +1,23 @@
+package com.example.onlinejudge.judge.codesandbox.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class ExecuteCodeResponse {
+
+    private List<String> outputList;
+
+    private String message;
+
+    private Integer status;
+
+    private JudgeInfo judgeInfo;
+}

+ 22 - 0
src/main/java/com/example/onlinejudge/judge/codesandbox/model/JudgeInfo.java

@@ -0,0 +1,22 @@
+package com.example.onlinejudge.judge.codesandbox.model;
+
+import lombok.Data;
+
+@Data
+public class JudgeInfo {
+
+    /**
+     * 程序执行信息
+     */
+    private String message;
+
+    /**
+     * 消耗内存(KB)
+     */
+    private Long memory;
+
+    /**
+     * 消耗时间
+     */
+    private Long time;
+}

+ 59 - 0
src/main/java/com/example/onlinejudge/judge/strategy/DefaultJudgeStrategy.java

@@ -0,0 +1,59 @@
+package com.example.onlinejudge.judge.strategy;
+
+import cn.hutool.json.JSONUtil;
+import com.example.onlinejudge.model.dto.question.JudgeCase;
+import com.example.onlinejudge.model.dto.question.JudgeConfig;
+import com.example.onlinejudge.model.dto.questionSubmit.JudgeInfo;
+import com.example.onlinejudge.model.entity.Question;
+import com.example.onlinejudge.model.enums.JudgeInfoMessageEnum;
+
+import java.util.List;
+
+public class DefaultJudgeStrategy implements  JudgeStrategy{
+    @Override
+    public JudgeInfo doJudge(JudgeContext judgeContext) {
+        JudgeInfo judgeInfo = judgeContext.getJudgeInfo();
+        Long memory = judgeInfo.getMemory();
+        Long time = judgeInfo.getTime();
+        List<String> inputList = judgeContext.getInputList();
+        List<String> outputList = judgeContext.getOutputList();
+        Question question = judgeContext.getQuestion();
+        List<JudgeCase> judgeCaseList = judgeContext.getJudgeCaseList();
+        JudgeInfoMessageEnum judgeInfoMessageEnum = JudgeInfoMessageEnum.ACCEPTED;
+        JudgeInfo judgeInfoResponse = new JudgeInfo();
+        judgeInfoResponse.setMemory(memory);
+        judgeInfoResponse.setTime(time);
+        // 先判断沙箱执行的结果输出数量是否和预期输出数量相等
+        if (outputList.size() != inputList.size()) {
+            judgeInfoMessageEnum = JudgeInfoMessageEnum.WRONG_ANSWER;
+            judgeInfoResponse.setMessage(judgeInfoMessageEnum.getValue());
+            return judgeInfoResponse;
+        }
+        // 依次判断每一项输出和预期输出是否相等
+        for (int i = 0; i < judgeCaseList.size(); i++) {
+            JudgeCase judgeCase = judgeCaseList.get(i);
+            if (!judgeCase.getOutput().equals(outputList.get(i))) {
+                judgeInfoMessageEnum = JudgeInfoMessageEnum.WRONG_ANSWER;
+                judgeInfoResponse.setMessage(judgeInfoMessageEnum.getValue());
+                return judgeInfoResponse;
+            }
+        }
+        // 判断题目限制
+        String judgeConfigStr = question.getJudgeConfig();
+        JudgeConfig judgeConfig = JSONUtil.toBean(judgeConfigStr, JudgeConfig.class);
+        Long needMemoryLimit = judgeConfig.getMemoryLimit();
+        Long needTimeLimit = judgeConfig.getTimeLimit();
+        if (memory > needMemoryLimit) {
+            judgeInfoMessageEnum = JudgeInfoMessageEnum.MEMORY_LIMIT_EXCEEDED;
+            judgeInfoResponse.setMessage(judgeInfoMessageEnum.getValue());
+            return judgeInfoResponse;
+        }
+        if (time > needTimeLimit) {
+            judgeInfoMessageEnum = JudgeInfoMessageEnum.TIME_LIMIT_EXCEEDED;
+            judgeInfoResponse.setMessage(judgeInfoMessageEnum.getValue());
+            return judgeInfoResponse;
+        }
+        judgeInfoResponse.setMessage(judgeInfoMessageEnum.getValue());
+        return judgeInfoResponse;
+    }
+}

+ 61 - 0
src/main/java/com/example/onlinejudge/judge/strategy/JavaLanguageJudgeStrategy.java

@@ -0,0 +1,61 @@
+package com.example.onlinejudge.judge.strategy;
+
+import cn.hutool.json.JSONUtil;
+import com.example.onlinejudge.model.dto.question.JudgeCase;
+import com.example.onlinejudge.model.dto.question.JudgeConfig;
+import com.example.onlinejudge.model.dto.questionSubmit.JudgeInfo;
+import com.example.onlinejudge.model.entity.Question;
+import com.example.onlinejudge.model.enums.JudgeInfoMessageEnum;
+
+import java.util.List;
+
+public class JavaLanguageJudgeStrategy implements JudgeStrategy{
+    @Override
+    public JudgeInfo doJudge(JudgeContext judgeContext) {
+        JudgeInfo judgeInfo = judgeContext.getJudgeInfo();
+        Long memory = judgeInfo.getMemory();
+        Long time = judgeInfo.getTime();
+        List<String> inputList = judgeContext.getInputList();
+        List<String> outputList = judgeContext.getOutputList();
+        Question question = judgeContext.getQuestion();
+        List<JudgeCase> judgeCaseList = judgeContext.getJudgeCaseList();
+        JudgeInfoMessageEnum judgeInfoMessageEnum = JudgeInfoMessageEnum.ACCEPTED;
+        JudgeInfo judgeInfoResponse = new JudgeInfo();
+        judgeInfoResponse.setMemory(memory);
+        judgeInfoResponse.setTime(time);
+        // 先判断沙箱执行的结果输出数量是否和预期输出数量相等
+        if (outputList.size() != inputList.size()) {
+            judgeInfoMessageEnum = JudgeInfoMessageEnum.WRONG_ANSWER;
+            judgeInfoResponse.setMessage(judgeInfoMessageEnum.getValue());
+            return judgeInfoResponse;
+        }
+        // 依次判断每一项输出和预期输出是否相等
+        for (int i = 0; i < judgeCaseList.size(); i++) {
+            JudgeCase judgeCase = judgeCaseList.get(i);
+            if (!judgeCase.getOutput().equals(outputList.get(i))) {
+                judgeInfoMessageEnum = JudgeInfoMessageEnum.WRONG_ANSWER;
+                judgeInfoResponse.setMessage(judgeInfoMessageEnum.getValue());
+                return judgeInfoResponse;
+            }
+        }
+        // 判断题目限制
+        String judgeConfigStr = question.getJudgeConfig();
+        JudgeConfig judgeConfig = JSONUtil.toBean(judgeConfigStr, JudgeConfig.class);
+        Long needMemoryLimit = judgeConfig.getMemoryLimit();
+        Long needTimeLimit = judgeConfig.getTimeLimit();
+        if (memory > needMemoryLimit) {
+            judgeInfoMessageEnum = JudgeInfoMessageEnum.MEMORY_LIMIT_EXCEEDED;
+            judgeInfoResponse.setMessage(judgeInfoMessageEnum.getValue());
+            return judgeInfoResponse;
+        }
+        // Java 程序本身需要额外执行 10 秒钟
+        long JAVA_PROGRAM_TIME_COST = 10000L;
+        if ((time - JAVA_PROGRAM_TIME_COST) > needTimeLimit) {
+            judgeInfoMessageEnum = JudgeInfoMessageEnum.TIME_LIMIT_EXCEEDED;
+            judgeInfoResponse.setMessage(judgeInfoMessageEnum.getValue());
+            return judgeInfoResponse;
+        }
+        judgeInfoResponse.setMessage(judgeInfoMessageEnum.getValue());
+        return judgeInfoResponse;
+    }
+}

+ 25 - 0
src/main/java/com/example/onlinejudge/judge/strategy/JudgeContext.java

@@ -0,0 +1,25 @@
+package com.example.onlinejudge.judge.strategy;
+
+import com.example.onlinejudge.model.dto.question.JudgeCase;
+import com.example.onlinejudge.model.dto.questionSubmit.JudgeInfo;
+import com.example.onlinejudge.model.entity.Question;
+import com.example.onlinejudge.model.entity.QuestionSubmit;
+import lombok.Data;
+import java.util.List;
+@Data
+public class JudgeContext {
+
+    private JudgeInfo judgeInfo;
+
+    private List<String> inputList;
+
+    private List<String> outputList;
+
+    private List<JudgeCase> judgeCaseList;
+
+    private Question question;
+
+    private QuestionSubmit questionSubmit;
+
+
+}

+ 10 - 0
src/main/java/com/example/onlinejudge/judge/strategy/JudgeStrategy.java

@@ -0,0 +1,10 @@
+package com.example.onlinejudge.judge.strategy;
+
+import com.example.onlinejudge.model.dto.questionSubmit.JudgeInfo;
+
+/**
+ * 判题策略
+ */
+public interface JudgeStrategy {
+    JudgeInfo doJudge(JudgeContext judgeContext);
+}

+ 8 - 0
src/main/java/com/example/onlinejudge/mapper/QuestionMapper.java

@@ -0,0 +1,8 @@
+package com.example.onlinejudge.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.example.onlinejudge.model.entity.Question;
+
+public interface QuestionMapper extends BaseMapper<Question> {
+
+}

+ 12 - 2
src/main/java/com/example/onlinejudge/mapper/QuestionSubmitMapper.java

@@ -2,8 +2,18 @@ package com.example.onlinejudge.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.example.onlinejudge.model.entity.QuestionSubmit;
-import org.apache.ibatis.annotations.Mapper;
 
-@Mapper
+
+/**
+* @author 201250081
+* @description 针对表【question_submit】的数据库操作Mapper
+* @createDate 2023-08-18 18:18:47
+* @Entity generator.domain.QuestionSubmit
+*/
 public interface QuestionSubmitMapper extends BaseMapper<QuestionSubmit> {
+
 }
+
+
+
+

+ 42 - 0
src/main/java/com/example/onlinejudge/model/dto/question/QuestionAddRequest.java

@@ -0,0 +1,42 @@
+package com.example.onlinejudge.model.dto.question;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class QuestionAddRequest implements Serializable {
+
+        /**
+        * 标题
+        */
+        private String title;
+
+        /**
+        * 内容
+        */
+        private String content;
+
+        /**
+        * 标签列表
+        */
+        private List<String> tags;
+
+        /**
+        * 题目答案
+        */
+        private String answer;
+
+        /**
+        * 判题用例
+        */
+        private List<JudgeCase> judgeCase;
+
+        /**
+        * 判题配置
+        */
+        private JudgeConfig judgeConfig;
+
+        private static final long serialVersionUID = 1L;
+}

+ 42 - 0
src/main/java/com/example/onlinejudge/model/dto/question/QuestionEditRequest.java

@@ -0,0 +1,42 @@
+package com.example.onlinejudge.model.dto.question;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class QuestionEditRequest implements Serializable{
+
+        /**
+        * 标题
+        */
+        private String title;
+
+        /**
+        * 内容
+        */
+        private String content;
+
+        /**
+        * 标签列表
+        */
+        private List<String> tags;
+
+        /**
+        * 题目答案
+        */
+        private String answer;
+
+        /**
+        * 判题用例
+        */
+        private List<JudgeCase> judgeCase;
+
+        /**
+        * 判题配置
+        */
+        private JudgeConfig judgeConfig;
+
+        private static final long serialVersionUID = 1L;
+}

+ 45 - 0
src/main/java/com/example/onlinejudge/model/dto/question/QuestionQueryRequest.java

@@ -0,0 +1,45 @@
+package com.example.onlinejudge.model.dto.question;
+
+import com.example.onlinejudge.common.PageRequest;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+import java.util.List;
+
+
+@Data
+public class QuestionQueryRequest extends PageRequest implements Serializable {
+
+    /**
+     * id
+     */
+    private Long id;
+
+    /**
+     * 标题
+     */
+    private String title;
+
+    /**
+     * 内容
+     */
+    private String content;
+
+    /**
+     * 标签列表
+     */
+    private List<String> tags;
+
+    /**
+     * 题目答案
+     */
+    private String answer;
+
+    /**
+     * 创建用户 id
+     */
+    private Long userId;
+
+    private static final long serialVersionUID = 1L;
+}

+ 47 - 0
src/main/java/com/example/onlinejudge/model/dto/question/QuestionUpdateRequest.java

@@ -0,0 +1,47 @@
+package com.example.onlinejudge.model.dto.question;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class QuestionUpdateRequest implements Serializable {
+
+    /**
+     * id
+     */
+    private Long id;
+
+    /**
+     * 标题
+     */
+    private String title;
+
+    /**
+     * 内容
+     */
+    private String content;
+
+    /**
+     * 标签列表
+     */
+    private List<String> tags;
+
+    /**
+     * 题目答案
+     */
+    private String answer;
+
+    /**
+     * 判题用例
+     */
+    private List<JudgeCase> judgeCase;
+
+    /**
+     * 判题配置
+     */
+    private JudgeConfig judgeConfig;
+
+    private static final long serialVersionUID = 1L;
+}

+ 20 - 6
src/main/java/com/example/onlinejudge/model/dto/questionSubmit/QuestionSubmitQueryRequest.java

@@ -1,24 +1,38 @@
 package com.example.onlinejudge.model.dto.questionSubmit;
 
+import com.example.onlinejudge.common.PageRequest;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 import java.io.Serializable;
 
 @ApiModel("查询题目请求")
 @Data
-public class QuestionSubmitQueryRequest implements Serializable {
+@EqualsAndHashCode(callSuper = true)
+public class QuestionSubmitQueryRequest extends PageRequest implements Serializable {
 
-        @ApiModelProperty("编程语言")
+        /**
+         * 编程语言
+         */
         private String language;
 
-        @ApiModelProperty("用户代码")
-        private String code;
+        /**
+         * 提交状态
+         */
+        private Integer status;
 
-        @ApiModelProperty("题目ID")
+        /**
+         * 题目 id
+         */
         private Long questionId;
 
-        private static final long serialVersionUID = 1L;
 
+        /**
+         * 用户 id
+         */
+        private Long userId;
+
+        private static final long serialVersionUID = 1L;
 }

+ 0 - 2
src/main/java/com/example/onlinejudge/model/entity/SubmitCode.java

@@ -57,6 +57,4 @@ public class SubmitCode {
 
     @ApiModelProperty("状态")
     String state;
-
-
 }

+ 38 - 13
src/main/java/com/example/onlinejudge/service/QuestionService.java

@@ -1,24 +1,49 @@
 package com.example.onlinejudge.service;
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.example.onlinejudge.model.VO.QuestionVO;
+import com.example.onlinejudge.model.dto.question.QuestionQueryRequest;
+import com.example.onlinejudge.model.entity.Question;
 import com.example.onlinejudge.model.entity.result.Result;
 
-public interface QuestionService {
+import javax.servlet.http.HttpServletRequest;
+
+public interface QuestionService extends IService<Question> {
+    /**
+     * 校验
+     *
+     * @param question
+     * @param add
+     */
+    void validQuestion(Question question, boolean add);
+
+    /**
+     * 获取查询条件
+     *
+     * @param questionQueryRequest
+     * @return
+     */
+    QueryWrapper<Question> getQueryWrapper(QuestionQueryRequest questionQueryRequest);
+
     /**
-     * 接受用户提交的解决方案
-     * @param questionID 问题id
-     * @param code 用户提交的代码
-     * @param language 使用的语言
-     * @param userCases 用户自测用例
-     * @param judgeMode 判断模式
+     * 获取题目封装
+     *
+     * @param question
+     * @param request
      * @return
      */
-    Result receiveCode(Long questionID, String code, String language, String userCases, Integer judgeMode);
+    QuestionVO getQuestionVO(Question question, HttpServletRequest request);
 
     /**
-     * 判断本次用户提交的解决方案是否合法
-     * @param userId 用户id
-     * @param questionID wentiid
+     * 分页获取题目封装
+     *
+     * @param questionPage
+     * @param request
      * @return
      */
-    boolean checkIsSubmitValid(Long userId, Long questionID);
-}
+    Page<QuestionVO> getQuestionVOPage(Page<Question> questionPage, HttpServletRequest request);
+
+
+}

+ 49 - 0
src/main/java/com/example/onlinejudge/service/QuestionSubmitService.java

@@ -0,0 +1,49 @@
+package com.example.onlinejudge.service;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.example.onlinejudge.model.VO.QuestionSubmitVO;
+import com.example.onlinejudge.model.dto.questionSubmit.QuestionSubmitAddRequest;
+import com.example.onlinejudge.model.dto.questionSubmit.QuestionSubmitQueryRequest;
+import com.example.onlinejudge.model.entity.QuestionSubmit;
+import com.example.onlinejudge.model.entity.User;
+
+public interface QuestionSubmitService extends IService<QuestionSubmit> {
+
+    /**
+     * 题目提交
+     *
+     * @param questionSubmitAddRequest 题目提交信息
+     * @param loginUser
+     * @return
+     */
+    long doQuestionSubmit(QuestionSubmitAddRequest questionSubmitAddRequest, User loginUser);
+
+    /**
+     * 获取查询条件
+     *
+     * @param questionSubmitQueryRequest
+     * @return
+     */
+    QueryWrapper<QuestionSubmit> getQueryWrapper(QuestionSubmitQueryRequest questionSubmitQueryRequest);
+
+    /**
+     * 获取题目封装
+     *
+     * @param questionSubmit
+     * @param loginUser
+     * @return
+     */
+    QuestionSubmitVO getQuestionSubmitVO(QuestionSubmit questionSubmit, User loginUser);
+
+    /**
+     * 分页获取题目封装
+     *
+     * @param questionSubmitPage
+     * @param loginUser
+     * @return
+     */
+    Page<QuestionSubmitVO> getQuestionSubmitVOPage(Page<QuestionSubmit> questionSubmitPage, User loginUser);
+}

+ 2 - 0
src/main/java/com/example/onlinejudge/service/UserService.java

@@ -5,4 +5,6 @@ import com.example.onlinejudge.model.entity.result.Result;
 
 public interface UserService {
     Result login(String username, String password);
+
+    String getLoginUser();
 }

+ 139 - 60
src/main/java/com/example/onlinejudge/service/impl/QuestionServiceImpl.java

@@ -2,85 +2,164 @@ package com.example.onlinejudge.service.impl;
 
 import cn.dev33.satoken.stp.StpUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.example.onlinejudge.common.ErrorCode;
+import com.example.onlinejudge.constant.CommonConstant;
+import com.example.onlinejudge.exception.BusinessException;
+import com.example.onlinejudge.exception.ThrowUtils;
+import com.example.onlinejudge.mapper.QuestionMapper;
 import com.example.onlinejudge.mapper.QuestionSubmitMapper;
+import com.example.onlinejudge.model.VO.QuestionVO;
+import com.example.onlinejudge.model.VO.UserVO;
+import com.example.onlinejudge.model.dto.question.QuestionQueryRequest;
+import com.example.onlinejudge.model.entity.Question;
 import com.example.onlinejudge.model.entity.QuestionSubmit;
+import com.example.onlinejudge.model.entity.User;
 import com.example.onlinejudge.model.entity.result.Result;
 import com.example.onlinejudge.model.entity.result.ResultCode;
 import com.example.onlinejudge.model.enums.JudgeInfoMessageEnum;
 import com.example.onlinejudge.model.enums.QuestionSubmitLanguageEnum;
 import com.example.onlinejudge.service.QuestionService;
+import com.example.onlinejudge.service.UserService;
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+//import org.apache.commons.collections4.CollectionUtils;
 
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
 import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 
 @Service
-public class QuestionServiceImpl implements QuestionService {
-    @Autowired
-    private QuestionSubmitMapper questionSubmitMapper;
+public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question>
+        implements QuestionService{
 
+
+    @Resource
+    private UserService userService;
+
+    /**
+     * 校验题目是否合法
+     * @param question
+     * @param add
+     */
     @Override
-    public Result receiveCode(Long questionID, String code, String language, String userCases, Integer judgeMode) {
-        Long userID = StpUtil.getLoginIdAsLong();
-        if (questionID == null)
-            return Result.error(ResultCode.PARAM_IS_INVALID);
-        String chooseLanguage;
-        if (QuestionSubmitLanguageEnum.JAVA.getValue().equals(language)) {
-            chooseLanguage = QuestionSubmitLanguageEnum.JAVA.getValue();
-        } else if (QuestionSubmitLanguageEnum.C.getValue().equals(language)) {
-            chooseLanguage = QuestionSubmitLanguageEnum.C.getValue();
-        } else if (QuestionSubmitLanguageEnum.CPP.getValue().equals(language)) {
-            chooseLanguage = QuestionSubmitLanguageEnum.CPP.getValue();
-        } else {
-            return Result.error(ResultCode.PARAM_IS_INVALID.getCode(), "空或未知的编程语言");
+    public void validQuestion(Question question, boolean add) {
+        if (question == null) {
+            throw new BusinessException(ErrorCode.PARAMS_ERROR);
+        }
+        String title = question.getTitle();
+        String content = question.getContent();
+        String tags = question.getTags();
+        String answer = question.getAnswer();
+        String judgeCase = question.getJudgeCase();
+        String judgeConfig = question.getJudgeConfig();
+        // 创建时,参数不能为空
+        if (add) {
+            ThrowUtils.throwIf(StringUtils.isAnyBlank(title, content, tags), ErrorCode.PARAMS_ERROR);
+        }
+        // 有参数则校验
+        if (StringUtils.isNotBlank(title) && title.length() > 80) {
+            throw new BusinessException(ErrorCode.PARAMS_ERROR, "标题过长");
+        }
+        if (StringUtils.isNotBlank(content) && content.length() > 8192) {
+            throw new BusinessException(ErrorCode.PARAMS_ERROR, "内容过长");
         }
-        if (!checkIsSubmitValid(userID, questionID))
-            return Result.error(ResultCode.SYSTEM_ERROR.getCode(), "频繁提交,请稍后再试");
-        QuestionSubmit questionSubmit;
-        if (judgeMode == 0) {
-            questionSubmit = new QuestionSubmit(
-                    null,
-                    chooseLanguage,
-                    code,
-                    JudgeInfoMessageEnum.WAITING.getValue(),
-                    0, questionID, userID,
-                    new Date(),
-                    new Date(),
-                    null,
-                    null,
-                    0,
-                    0);
-        } else {
-            questionSubmit = new QuestionSubmit(
-                    null,
-                    chooseLanguage,
-                    code,
-                    JudgeInfoMessageEnum.WAITING.getValue(),
-                    0, questionID, userID,
-                    new Date(),
-                    new Date(),
-                    userCases,
-                    null,
-                    1,
-                    0);
+        if (StringUtils.isNotBlank(answer) && answer.length() > 8192) {
+            throw new BusinessException(ErrorCode.PARAMS_ERROR, "答案过长");
+        }
+        if (StringUtils.isNotBlank(judgeCase) && judgeCase.length() > 8192) {
+            throw new BusinessException(ErrorCode.PARAMS_ERROR, "判题用例过长");
+        }
+        if (StringUtils.isNotBlank(judgeConfig) && judgeConfig.length() > 8192) {
+            throw new BusinessException(ErrorCode.PARAMS_ERROR, "判题配置过长");
         }
-        questionSubmitMapper.insert(questionSubmit);
-        System.out.println(questionSubmit);
-        // TODO: 1.提交代码到判题系统 2.更改数据库刷新状态 3.返回判题信息
-        return Result.success();
     }
 
+    /**
+     * 获取查询包装类(用户根据哪些字段查询,根据前端传来的请求对象,得到 mybatis 框架支持的查询 QueryWrapper 类)
+     *
+     * @param questionQueryRequest
+     * @return
+     */
     @Override
-    public boolean checkIsSubmitValid(Long userId, Long questionID) {
-        QueryWrapper<QuestionSubmit> queryWrapper = new QueryWrapper<>();
-        queryWrapper.eq("user_id", userId).eq("question_id", questionID).orderByDesc("create_time").last("limit 1");
-        QuestionSubmit record = questionSubmitMapper.selectOne(queryWrapper);
-        System.out.println(record);
-        if (record == null) {
-            return true;
-        } else if (record.getStatus() == 0 || record.getStatus() == 1) {
-            return false;
-        } else return System.currentTimeMillis() - record.getCreateTime().getTime() >= 2000;
+    public QueryWrapper<Question> getQueryWrapper(QuestionQueryRequest questionQueryRequest) {
+        QueryWrapper<Question> queryWrapper = new QueryWrapper<>();
+        if (questionQueryRequest == null) {
+            return queryWrapper;
+        }
+        Long id = questionQueryRequest.getId();
+        String title = questionQueryRequest.getTitle();
+        String content = questionQueryRequest.getContent();
+        List<String> tags = questionQueryRequest.getTags();
+        String answer = questionQueryRequest.getAnswer();
+        Long userId = questionQueryRequest.getUserId();
+        String sortField = questionQueryRequest.getSortField();
+        String sortOrder = questionQueryRequest.getSortOrder();
+
+        // 拼接查询条件
+        queryWrapper.like(StringUtils.isNotBlank(title), "title", title);
+        queryWrapper.like(StringUtils.isNotBlank(content), "content", content);
+        queryWrapper.like(StringUtils.isNotBlank(answer), "answer", answer);
+//        if (CollectionUtils.isNotEmpty(tags)) {
+//            for (String tag : tags) {
+//                queryWrapper.like("tags", "\"" + tag + "\"");
+//            }
+//        }
+        queryWrapper.eq(ObjectUtils.isNotEmpty(id), "id", id);
+        queryWrapper.eq(ObjectUtils.isNotEmpty(userId), "userId", userId);
+        queryWrapper.eq("isDelete", false);
+//        queryWrapper.orderBy(SqlUtils.validSortField(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
+//                sortField);
+        return queryWrapper;
     }
-}
+
+    @Override
+    public QuestionVO getQuestionVO(Question question, HttpServletRequest request) {
+        QuestionVO questionVO = QuestionVO.objToVo(question);
+        // 1. 关联查询用户信息
+        Long userId = question.getUserId();
+        User user = null;
+//        if (userId != null && userId > 0) {
+//            user = userService.getById(userId);
+//        }
+//        UserVO userVO = userService.getUserVO(user);
+//        questionVO.setUserVO(userVO);
+        return questionVO;
+    }
+
+    @Override
+    public Page<QuestionVO> getQuestionVOPage(Page<Question> questionPage, HttpServletRequest request) {
+        List<Question> questionList = questionPage.getRecords();
+        Page<QuestionVO> questionVOPage = new Page<>(questionPage.getCurrent(), questionPage.getSize(), questionPage.getTotal());
+//        if (CollectionUtils.isEmpty(questionList)) {
+//            return questionVOPage;
+//        }
+        // 1. 关联查询用户信息
+        Set<Long> userIdSet = questionList.stream().map(Question::getUserId).collect(Collectors.toSet());
+//        Map<Long, List<User>> userIdUserListMap = userService.listByIds(userIdSet).stream()
+//                .collect(Collectors.groupingBy(User::getId));
+        // 填充信息
+        List<QuestionVO> questionVOList = questionList.stream().map(question -> {
+            QuestionVO questionVO = QuestionVO.objToVo(question);
+            Long userId = question.getUserId();
+            User user = null;
+//            if (userIdUserListMap.containsKey(userId)) {
+//                user = userIdUserListMap.get(userId).get(0);
+//            }
+//            questionVO.setUserVO(userService.getUserVO(user));
+            return questionVO;
+        }).collect(Collectors.toList());
+        questionVOPage.setRecords(questionVOList);
+        return questionVOPage;
+    }
+
+
+}

+ 4 - 0
src/main/java/com/example/onlinejudge/service/impl/QuestionSubmitServiceImpl.java

@@ -0,0 +1,4 @@
+package com.example.onlinejudge.service.impl;
+
+public class QuestionSubmitServiceImpl {
+}

+ 5 - 0
src/main/java/com/example/onlinejudge/service/impl/UserServiceImpl.java

@@ -43,4 +43,9 @@ public class UserServiceImpl implements UserService {
         return Result.error(ResultCode.USER_LOGIN_ERROR);
     }
 
+    @Override
+    public String getLoginUser() {
+        return StpUtil.getLoginId().toString();
+    }
+
 }