Browse Source

增加代码提交功能,修复部分bug

rongrunxiang 1 năm trước cách đây
mục cha
commit
8cb6903382
30 tập tin đã thay đổi với 272 bổ sung193 xóa
  1. 1 1
      src/main/java/com/example/onlinejudge/common/result/Result.java
  2. 9 3
      src/main/java/com/example/onlinejudge/common/result/ResultCode.java
  3. 2 3
      src/main/java/com/example/onlinejudge/controller/JudgeController.java
  4. 11 35
      src/main/java/com/example/onlinejudge/controller/QuestionController.java
  5. 9 28
      src/main/java/com/example/onlinejudge/controller/QuestionSubmitController.java
  6. 4 5
      src/main/java/com/example/onlinejudge/controller/UserController.java
  7. 1 1
      src/main/java/com/example/onlinejudge/exception/BusinessException.java
  8. 3 3
      src/main/java/com/example/onlinejudge/exception/GlobalExceptionHandler.java
  9. 1 1
      src/main/java/com/example/onlinejudge/exception/ThrowUtils.java
  10. 3 1
      src/main/java/com/example/onlinejudge/judge/JudgeManager.java
  11. 92 2
      src/main/java/com/example/onlinejudge/judge/JudgeServiceImpl.java
  12. 26 0
      src/main/java/com/example/onlinejudge/judge/codesandbox/CodeSandboxFactory.java
  13. 23 1
      src/main/java/com/example/onlinejudge/judge/codesandbox/impl/RemoteCodeSandbox.java
  14. 1 1
      src/main/java/com/example/onlinejudge/judge/strategy/DefaultJudgeStrategy.java
  15. 1 1
      src/main/java/com/example/onlinejudge/judge/strategy/JavaLanguageJudgeStrategy.java
  16. 1 1
      src/main/java/com/example/onlinejudge/judge/strategy/JudgeContext.java
  17. 1 1
      src/main/java/com/example/onlinejudge/judge/strategy/JudgeStrategy.java
  18. 2 0
      src/main/java/com/example/onlinejudge/mapper/QuestionMapper.java
  19. 2 1
      src/main/java/com/example/onlinejudge/mapper/QuestionSubmitMapper.java
  20. 1 2
      src/main/java/com/example/onlinejudge/model/VO/QuestionSubmitVO.java
  21. 0 20
      src/main/java/com/example/onlinejudge/model/dto/questionSubmit/JudgeInfo.java
  22. 0 60
      src/main/java/com/example/onlinejudge/model/entity/SubmitCode.java
  23. 0 1
      src/main/java/com/example/onlinejudge/service/QuestionService.java
  24. 1 2
      src/main/java/com/example/onlinejudge/service/UserService.java
  25. 1 2
      src/main/java/com/example/onlinejudge/service/impl/QuestionServiceImpl.java
  26. 6 3
      src/main/java/com/example/onlinejudge/service/impl/QuestionSubmitServiceImpl.java
  27. 2 8
      src/main/java/com/example/onlinejudge/service/impl/UserServiceImpl.java
  28. 8 6
      src/main/resources/application.yml
  29. 30 0
      src/main/resources/mapper/QuestionMapper.xml
  30. 30 0
      src/main/resources/mapper/QuestionSubmitMapper.xml

+ 1 - 1
src/main/java/com/example/onlinejudge/model/entity/result/Result.java → src/main/java/com/example/onlinejudge/common/result/Result.java

@@ -1,4 +1,4 @@
-package com.example.onlinejudge.model.entity.result;
+package com.example.onlinejudge.common.result;
 
 import lombok.Data;
 

+ 9 - 3
src/main/java/com/example/onlinejudge/model/entity/result/ResultCode.java → src/main/java/com/example/onlinejudge/common/result/ResultCode.java

@@ -1,4 +1,4 @@
-package com.example.onlinejudge.model.entity.result;
+package com.example.onlinejudge.common.result;
 
 public enum ResultCode {
     /* 成功状态码 */
@@ -22,9 +22,15 @@ public enum ResultCode {
     DATABASE_DUPLICATE_INSERT(3002,"重复插入"),
     NOT_FOUND_ERROR(3003,"请求的参数不存在"),
 
+    /* 业务错误 4001-4999 */
+
+    /* 系统错误 5001-5999 */
+    SYSTEM_ERROR(5000, "系统异常,请稍后重试"),
+    API_REQUEST_ERROR(5001,"接口调用失败"),
+    OPERATION_ERROR(5002,"操作失败"),
+
+
 
-    /* 系统错误 10001-19999 */
-    SYSTEM_ERROR(10000, "系统异常,请稍后重试")
     ;
     private final Integer code;
     private final String message;

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

@@ -1,8 +1,6 @@
 package com.example.onlinejudge.controller;
 
-import com.example.onlinejudge.model.entity.result.Result;
-import com.example.onlinejudge.model.entity.result.ResultCode;
-import com.example.onlinejudge.model.enums.QuestionSubmitLanguageEnum;
+import com.example.onlinejudge.common.result.Result;
 import com.example.onlinejudge.service.QuestionService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiImplicitParam;
@@ -13,6 +11,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
 @Api(tags = "提交判题")
+@Deprecated
 @RestController
 @RequestMapping("/api/judge")
 @Slf4j

+ 11 - 35
src/main/java/com/example/onlinejudge/controller/QuestionController.java

@@ -1,6 +1,5 @@
 package com.example.onlinejudge.controller;
 
-import com.alibaba.druid.wall.violation.ErrorCode;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 
 import com.example.onlinejudge.common.DeleteRequest;
@@ -10,11 +9,12 @@ import com.example.onlinejudge.exception.BusinessException;
 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.result.Result;
-import com.example.onlinejudge.model.entity.result.ResultCode;
+import com.example.onlinejudge.common.result.Result;
+import com.example.onlinejudge.common.result.ResultCode;
 import com.example.onlinejudge.service.QuestionService;
 import com.example.onlinejudge.service.UserService;
 import com.google.gson.Gson;
+import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
@@ -24,8 +24,10 @@ import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
+import java.util.Date;
 import java.util.List;
 
+@Api(tags = "对题目进行增删改查")
 @RestController
 @RequestMapping("/question")
 @Slf4j
@@ -41,15 +43,8 @@ public class QuestionController {
 
     // region 增删改查
 
-    /**
-     * 创建题目
-     *
-     * @param questionAddRequest
-     * @param request
-     * @return
-     */
     @PostMapping("/add")
-    public Result<Long> addQuestion(@RequestBody QuestionAddRequest questionAddRequest, HttpServletRequest request) {
+    public Result<Long> addQuestion(@RequestBody QuestionAddRequest questionAddRequest) {
         if (questionAddRequest == null) {
             return Result.error(ResultCode.PARAM_IS_BLANK);
         }
@@ -68,9 +63,10 @@ public class QuestionController {
             question.setJudgeConfig(GSON.toJson(judgeConfig));
         }
         questionService.validQuestion(question, true);
-        //TODO:记录谁创建了这个题目 Done
         Long loginUserId = userService.getLoginUserId();
         question.setUserId(loginUserId);
+        question.setUpdateTime(new Date());
+        question.setCreateTime(new Date());
         boolean result = questionService.save(question);
         if(!result){
             return Result.error(ResultCode.PARAM_IS_INVALID);
@@ -80,15 +76,9 @@ public class QuestionController {
         return Result.success(newQuestionId);
     }
 
-    /**
-     * 删除
-     *
-     * @param deleteRequest
-     * @param request
-     * @return
-     */
+
     @PostMapping("/delete")
-    public Result<Boolean> deleteQuestion(@RequestBody DeleteRequest deleteRequest, HttpServletRequest request) {
+    public Result<Boolean> deleteQuestion(@RequestBody DeleteRequest deleteRequest) {
         if (deleteRequest == null || deleteRequest.getId() <= 0) {
             return Result.error(ResultCode.PARAM_IS_BLANK);
         }
@@ -98,9 +88,7 @@ public class QuestionController {
         if(oldQuestion == null){
             return Result.error(ResultCode.PARAM_IS_INVALID);
         }
-        //ThrowUtils.throwIf(oldQuestion == null, ErrorCode.NOT_FOUND_ERROR);
-        // 仅本人或管理员可删除
-        //TODO:判断是否是管理员 DONE
+
         if (userService.isAdmin(userService.getLoginUserId())) {
             return Result.error(ResultCode.PERMISSION_DENIED);
         }
@@ -135,9 +123,6 @@ public class QuestionController {
     }
 
     @ApiOperation(value = "根据id获取题目(封装类)")
-    @ApiImplicitParams({
-            @ApiImplicitParam(name = "id", value = "题目id", required = true, dataType = "long"),
-    })
     @GetMapping("/get/vo")
     public Result<QuestionVO> getQuestionVOById(long id, HttpServletRequest request) {
         if (id <= 0) {
@@ -152,9 +137,6 @@ public class QuestionController {
 
 
     @ApiOperation(value = "分页获取题目列表(封装类)")
-    @ApiImplicitParams(
-            @ApiImplicitParam(name = "questionQueryRequest", value = "查询条件", required = true, dataType = "QuestionQueryRequest")
-    )
     @PostMapping("/list/page/vo")
     public Result<Page<QuestionVO>> listQuestionVOByPage(@RequestBody QuestionQueryRequest questionQueryRequest,
                                                                HttpServletRequest request) {
@@ -171,9 +153,6 @@ public class QuestionController {
     }
 
     @ApiOperation(value = "分页获取当前用户创建的题目列表(封装类)")
-    @ApiImplicitParams(
-            @ApiImplicitParam(name = "questionQueryRequest", value = "查询条件", required = true, dataType = "QuestionQueryRequest")
-    )
     @PostMapping("/my/list/page/vo")
     public Result<Page<QuestionVO>> listMyQuestionVOByPage(@RequestBody QuestionQueryRequest questionQueryRequest,
                                                                  HttpServletRequest request) {
@@ -194,9 +173,6 @@ public class QuestionController {
     }
 
     @ApiOperation(value = "分页获取题目列表(仅管理员)")
-    @ApiImplicitParams(
-            @ApiImplicitParam(name = "questionQueryRequest", value = "查询条件", required = true, dataType = "QuestionQueryRequest")
-    )
     @PostMapping("/list/page")
     public Result<Page<Question>> listQuestionByPage(@RequestBody QuestionQueryRequest questionQueryRequest,
                                                            HttpServletRequest request) {

+ 9 - 28
src/main/java/com/example/onlinejudge/controller/QuestionSubmitController.java

@@ -8,11 +8,11 @@ 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.common.result.Result;
+import com.example.onlinejudge.common.result.ResultCode;
 import com.example.onlinejudge.service.QuestionSubmitService;
 import com.example.onlinejudge.service.UserService;
+import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
@@ -25,12 +25,8 @@ 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>
- */
+
+@Api(tags = "提交代码判题")
 @RestController
 @RequestMapping("/question_submit")
 @Slf4j
@@ -43,42 +39,27 @@ public class QuestionSubmitController {
     private UserService userService;
 
     @ApiOperation(value = "提交题目")
-    @ApiImplicitParams(
-            @ApiImplicitParam(name = "questionSubmitAddRequest", value = "提交题目的请求", required = true, dataType = "QuestionSubmitAddRequest", paramType = "body")
-    )
     @PostMapping("/")
-    public Result doQuestionSubmit(@RequestBody QuestionSubmitAddRequest questionSubmitAddRequest,
-                                   HttpServletRequest request) {
+    public Result doQuestionSubmit(@RequestBody QuestionSubmitAddRequest questionSubmitAddRequest) {
         if (questionSubmitAddRequest == null || questionSubmitAddRequest.getQuestionId() <= 0) {
+            //题目不存在
             return new Result(ResultCode.PARAM_IS_INVALID.getCode(),ResultCode.PARAM_IS_INVALID.getMessage());
         }
-        // TODO: 获取登录id DONE
         long logInId = StpUtil.getLoginIdAsLong();
+        System.out.println("logInId: " + logInId);
         long questionSubmitId = questionSubmitService.doQuestionSubmit(questionSubmitAddRequest, logInId);
         return Result.success(questionSubmitId);
     }
 
-    /**
-     * 分页获取题目提交列表(除了管理员外,普通用户只能看到非答案、提交代码等公开信息)
-     *
-     * @param questionSubmitQueryRequest
-     * @param request
-     * @return
-     */
     @ApiOperation(value = "分页获取题目提交列表(除了管理员外,普通用户只能看到非答案、提交代码等公开信息)")
-    @ApiImplicitParams(
-            @ApiImplicitParam(name = "questionSubmitQueryRequest", value = "查询条件", required = true, dataType = "QuestionSubmitQueryRequest", paramType = "body")
-    )
     @PostMapping("/list/page")
-    public Result<Page<QuestionSubmitVO>> listQuestionSubmitByPage(@RequestBody QuestionSubmitQueryRequest questionSubmitQueryRequest,
-                                                                         HttpServletRequest request) {
+    public Result<Page<QuestionSubmitVO>> listQuestionSubmitByPage(@RequestBody QuestionSubmitQueryRequest questionSubmitQueryRequest) {
         long current = questionSubmitQueryRequest.getCurrent();
         long size = questionSubmitQueryRequest.getPageSize();
         // 从数据库中查询原始的题目提交分页信息
         Page<QuestionSubmit> questionSubmitPage = questionSubmitService.page(new Page<>(current, size),
                 questionSubmitService.getQueryWrapper(questionSubmitQueryRequest));
         final long logInId = StpUtil.getLoginIdAsLong();
-        // TODO 返回脱敏信息 DONE
         return Result.success(questionSubmitService.getQuestionSubmitVOPage(questionSubmitPage, logInId));
     }
 

+ 4 - 5
src/main/java/com/example/onlinejudge/controller/UserController.java

@@ -1,21 +1,20 @@
 package com.example.onlinejudge.controller;
 
 import cn.dev33.satoken.stp.StpUtil;
-import cn.dev33.satoken.util.SaResult;
 import cn.hutool.core.util.StrUtil;
-import com.alibaba.druid.util.StringUtils;
 import com.example.onlinejudge.model.dto.user.UserLoginRequest;
-import com.example.onlinejudge.model.entity.result.Result;
-import com.example.onlinejudge.model.entity.result.ResultCode;
+import com.example.onlinejudge.common.result.Result;
+import com.example.onlinejudge.common.result.ResultCode;
 import com.example.onlinejudge.service.UserService;
+import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
 
 
+@Api(tags = "用户登录")
 @Controller
 @RequestMapping("/api/user")
 public class UserController {

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

@@ -1,7 +1,7 @@
 package com.example.onlinejudge.exception;
 
 
-import com.example.onlinejudge.model.entity.result.ResultCode;
+import com.example.onlinejudge.common.result.ResultCode;
 
 public class BusinessException extends RuntimeException {
     /**

+ 3 - 3
src/main/java/com/example/onlinejudge/exception/GlobalExceptionHandler.java

@@ -1,9 +1,8 @@
 package com.example.onlinejudge.exception;
 
 import cn.dev33.satoken.exception.NotLoginException;
-import cn.dev33.satoken.util.SaResult;
-import com.example.onlinejudge.model.entity.result.Result;
-import com.example.onlinejudge.model.entity.result.ResultCode;
+import com.example.onlinejudge.common.result.Result;
+import com.example.onlinejudge.common.result.ResultCode;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.web.bind.annotation.ExceptionHandler;
 import org.springframework.web.bind.annotation.RestControllerAdvice;
@@ -28,6 +27,7 @@ public class GlobalExceptionHandler {
     @ExceptionHandler(BusinessException.class)
     public Result<?> businessExceptionHandler(BusinessException e) {
         log.error("BusinessException", e);
+        System.out.println("发生异常");
         return Result.error(e.getCode(), e.getMessage());
     }
 }

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

@@ -1,6 +1,6 @@
 package com.example.onlinejudge.exception;
 
-import com.example.onlinejudge.model.entity.result.ResultCode;
+import com.example.onlinejudge.common.result.ResultCode;
 
 public class ThrowUtils {
 

+ 3 - 1
src/main/java/com/example/onlinejudge/judge/JudgeManager.java

@@ -1,15 +1,17 @@
 package com.example.onlinejudge.judge;
 
+import com.example.onlinejudge.judge.codesandbox.model.JudgeInfo;
 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;
+import org.springframework.stereotype.Service;
 
 /**
  * 判题管理(简化调用)
  */
+@Service
 public class JudgeManager {
 
         /**

+ 92 - 2
src/main/java/com/example/onlinejudge/judge/JudgeServiceImpl.java

@@ -1,11 +1,28 @@
 package com.example.onlinejudge.judge;
 
+import cn.hutool.json.JSONUtil;
+import com.example.onlinejudge.exception.BusinessException;
+import com.example.onlinejudge.judge.codesandbox.CodeSandbox;
+import com.example.onlinejudge.judge.codesandbox.CodeSandboxFactory;
+import com.example.onlinejudge.judge.codesandbox.CodeSandboxProxy;
+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.judge.strategy.JudgeContext;
+import com.example.onlinejudge.model.dto.question.JudgeCase;
+import com.example.onlinejudge.model.entity.Question;
 import com.example.onlinejudge.model.entity.QuestionSubmit;
+import com.example.onlinejudge.common.result.ResultCode;
+import com.example.onlinejudge.model.enums.QuestionSubmitStatusEnum;
 import com.example.onlinejudge.service.QuestionService;
 import com.example.onlinejudge.service.QuestionSubmitService;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
+import java.util.List;
+import java.util.stream.Collectors;
 
 @Service
 public class JudgeServiceImpl implements JudgeService{
@@ -14,8 +31,81 @@ public class JudgeServiceImpl implements JudgeService{
     private QuestionService questionService;
 
     @Resource
-    QuestionSubmitService questionSubmitService;
+    private QuestionSubmitService questionSubmitService;
+
+    @Resource
+    private JudgeManager judgeManager;
+
+    @Value("${codesandbox.type:example}")
+    private String type;
+
+    @Override
     public QuestionSubmit doJudge(long questionSubmitId) {
-        return null;
+        System.out.println("判题服务开始");
+        System.out.println("questionSubmitId: " + questionSubmitId);
+        // 1)传入题目的提交 id,获取到对应的题目、提交信息(包含代码、编程语言等)
+        QuestionSubmit questionSubmit = questionSubmitService.getById(questionSubmitId);
+        if (questionSubmit == null) {
+            System.out.println("提交信息不存在");
+            throw new BusinessException(ResultCode.NOT_FOUND_ERROR, "提交信息不存在");
+        }
+        Long questionId = questionSubmit.getQuestionId();
+        Question question = questionService.getById(questionId);
+        if (question == null) {
+            System.out.println("题目不存在");
+            throw new BusinessException(ResultCode.NOT_FOUND_ERROR, "题目不存在");
+        }
+        System.out.println("1结束");
+        // 2)如果题目提交状态不为等待中,就不用重复执行了
+        if (!questionSubmit.getStatus().equals(QuestionSubmitStatusEnum.WAITING.getValue())) {
+            throw new BusinessException(ResultCode.OPERATION_ERROR, "题目正在判题中");
+        }
+        System.out.println("2结束");
+        // 3)更改判题(题目提交)的状态为 “判题中”,防止重复执行
+        QuestionSubmit questionSubmitUpdate = new QuestionSubmit();
+        questionSubmitUpdate.setId(questionSubmitId);
+        questionSubmitUpdate.setStatus(QuestionSubmitStatusEnum.RUNNING.getValue());
+        boolean update = questionSubmitService.updateById(questionSubmitUpdate);
+        if (!update) {
+            throw new BusinessException(ResultCode.SYSTEM_ERROR, "题目状态更新错误");
+        }
+        System.out.println("准备开始判题");
+        // 4)调用沙箱,获取到执行结果
+        CodeSandbox codeSandbox = CodeSandboxFactory.newInstance(type);
+        System.out.println(codeSandbox);
+        codeSandbox = new CodeSandboxProxy(codeSandbox);
+        String language = questionSubmit.getLanguage();
+        String code = questionSubmit.getCode();
+        // 获取输入用例
+        String judgeCaseStr = question.getJudgeCase();
+        List<JudgeCase> judgeCaseList = JSONUtil.toList(judgeCaseStr, JudgeCase.class);
+        List<String> inputList = judgeCaseList.stream().map(JudgeCase::getInput).collect(Collectors.toList());
+        ExecuteCodeRequest executeCodeRequest = ExecuteCodeRequest.builder()
+                .code(code)
+                .language(language)
+                .inputList(inputList)
+                .build();
+        ExecuteCodeResponse executeCodeResponse = codeSandbox.executeCode(executeCodeRequest);
+        List<String> outputList = executeCodeResponse.getOutputList();
+        // 5)根据沙箱的执行结果,设置题目的判题状态和信息
+        JudgeContext judgeContext = new JudgeContext();
+        judgeContext.setJudgeInfo(executeCodeResponse.getJudgeInfo());
+        judgeContext.setInputList(inputList);
+        judgeContext.setOutputList(outputList);
+        judgeContext.setJudgeCaseList(judgeCaseList);
+        judgeContext.setQuestion(question);
+        judgeContext.setQuestionSubmit(questionSubmit);
+        JudgeInfo judgeInfo = judgeManager.doJudge(judgeContext);
+        // 6)修改数据库中的判题结果
+        questionSubmitUpdate = new QuestionSubmit();
+        questionSubmitUpdate.setId(questionSubmitId);
+        questionSubmitUpdate.setStatus(QuestionSubmitStatusEnum.SUCCEED.getValue());
+        questionSubmitUpdate.setJudgeInfo(JSONUtil.toJsonStr(judgeInfo));
+        update = questionSubmitService.updateById(questionSubmitUpdate);
+        if (!update) {
+            throw new BusinessException(ResultCode.SYSTEM_ERROR, "题目状态更新错误");
+        }
+        QuestionSubmit questionSubmitResult = questionSubmitService.getById(questionId);
+        return questionSubmitResult;
     }
 }

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

@@ -1,4 +1,30 @@
 package com.example.onlinejudge.judge.codesandbox;
 
+import com.example.onlinejudge.judge.codesandbox.impl.ExampleCodeSandbox;
+import com.example.onlinejudge.judge.codesandbox.impl.RemoteCodeSandbox;
+import com.example.onlinejudge.judge.codesandbox.impl.ThirdPartyCodeSandbox;
+
+
+/**
+ * 代码沙箱工厂(根据字符串参数创建指定的代码沙箱实例)
+ */
 public class CodeSandboxFactory {
+
+    public static CodeSandbox newInstance(String type){
+        switch (type){
+            case "example":
+                System.out.println("示例代码沙箱");
+                return new ExampleCodeSandbox();
+            case "remote":
+                System.out.println("远程代码沙箱");
+                return new RemoteCodeSandbox();
+            case "thirdParty":
+                System.out.println("第三方代码沙箱");
+                return new ThirdPartyCodeSandbox();
+            default:
+                System.out.println("默认代码沙箱");
+                return new RemoteCodeSandbox();
+        }
+    }
+
 }

+ 23 - 1
src/main/java/com/example/onlinejudge/judge/codesandbox/impl/RemoteCodeSandbox.java

@@ -1,13 +1,35 @@
 package com.example.onlinejudge.judge.codesandbox.impl;
 
+import cn.hutool.http.HttpUtil;
+import cn.hutool.json.JSONUtil;
+
+import com.example.onlinejudge.exception.BusinessException;
 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.common.result.ResultCode;
+import org.apache.commons.lang3.StringUtils;
 
 public class RemoteCodeSandbox implements CodeSandbox {
+
+    // 定义鉴权请求头和密钥
+    private static final String AUTH_REQUEST_HEADER = "auth";
+    private static final String AUTH_REQUEST_SECRET = "secretKey";
+
     @Override
     public ExecuteCodeResponse executeCode(ExecuteCodeRequest executeCodeRequest) {
         System.out.println("远程代码沙箱");
-        return null;
+        String url = "http://localhost:8090/executeCode";
+        String json = JSONUtil.toJsonStr(executeCodeRequest);
+        String responseStr = HttpUtil.createPost(url)
+                .header(AUTH_REQUEST_HEADER, AUTH_REQUEST_SECRET)
+                .body(json)
+                .execute()
+                .body();
+        if(StringUtils.isBlank(responseStr)){
+            throw new BusinessException(ResultCode.API_REQUEST_ERROR,"executeCode remoteSandbox error");
+        }
+        System.out.println(responseStr);
+        return JSONUtil.toBean(responseStr, ExecuteCodeResponse.class);
     }
 }

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

@@ -1,9 +1,9 @@
 package com.example.onlinejudge.judge.strategy;
 
 import cn.hutool.json.JSONUtil;
+import com.example.onlinejudge.judge.codesandbox.model.JudgeInfo;
 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;
 

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

@@ -1,9 +1,9 @@
 package com.example.onlinejudge.judge.strategy;
 
 import cn.hutool.json.JSONUtil;
+import com.example.onlinejudge.judge.codesandbox.model.JudgeInfo;
 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;
 

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

@@ -1,7 +1,7 @@
 package com.example.onlinejudge.judge.strategy;
 
+import com.example.onlinejudge.judge.codesandbox.model.JudgeInfo;
 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;

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

@@ -1,6 +1,6 @@
 package com.example.onlinejudge.judge.strategy;
 
-import com.example.onlinejudge.model.dto.questionSubmit.JudgeInfo;
+import com.example.onlinejudge.judge.codesandbox.model.JudgeInfo;
 
 /**
  * 判题策略

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

@@ -2,7 +2,9 @@ package com.example.onlinejudge.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.example.onlinejudge.model.entity.Question;
+import org.mapstruct.Mapper;
 
+@Mapper
 public interface QuestionMapper extends BaseMapper<Question> {
 
 }

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

@@ -2,9 +2,10 @@ package com.example.onlinejudge.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.example.onlinejudge.model.entity.QuestionSubmit;
+import org.mapstruct.Mapper;
 
 
-
+@Mapper
 public interface QuestionSubmitMapper extends BaseMapper<QuestionSubmit> {
 
 }

+ 1 - 2
src/main/java/com/example/onlinejudge/model/VO/QuestionSubmitVO.java

@@ -1,11 +1,10 @@
 package com.example.onlinejudge.model.VO;
 
 import cn.hutool.json.JSONUtil;
-import com.example.onlinejudge.model.dto.questionSubmit.JudgeInfo;
+import com.example.onlinejudge.judge.codesandbox.model.JudgeInfo;
 import com.example.onlinejudge.model.entity.QuestionSubmit;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
-import io.swagger.annotations.ApiOperation;
 import lombok.Data;
 import org.springframework.beans.BeanUtils;
 

+ 0 - 20
src/main/java/com/example/onlinejudge/model/dto/questionSubmit/JudgeInfo.java

@@ -1,20 +0,0 @@
-package com.example.onlinejudge.model.dto.questionSubmit;
-
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
-import lombok.Data;
-
-@Data
-@ApiModel("评测信息")
-public class JudgeInfo {
-
-
-        @ApiModelProperty("程序执行信息")
-        private String message;
-
-        @ApiModelProperty("消耗内存(KB)")
-        private Long memory;
-
-        @ApiModelProperty("消耗时间(ms)")
-        private Long time;
-}

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

@@ -1,60 +0,0 @@
-package com.example.onlinejudge.model.entity;
-
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
-import lombok.Data;
-
-@Data
-@ApiModel("提交代码")
-public class SubmitCode {
-    @ApiModelProperty("提交代码id")
-    int id;
-
-    @ApiModelProperty("提交用户id")
-    int userID;
-
-    @ApiModelProperty("提交题目id")
-    int problemID;
-
-    @ApiModelProperty("提交时间")
-    String submitTime;
-
-    @ApiModelProperty("提交结果")
-    String result;
-
-    @ApiModelProperty("运行时间")
-    int runTime;
-
-    @ApiModelProperty("运行内存")
-    int runMemory;
-
-    @ApiModelProperty("提交代码")
-    String sourceCode;
-
-    @ApiModelProperty("语言id")
-    String language;
-
-    @ApiModelProperty("输入")
-    String stdin;
-
-    @ApiModelProperty("输出")
-    String stdout;
-
-    @ApiModelProperty("错误")
-    String stderr;
-
-    @ApiModelProperty("编译信息")
-    String compileInfo;
-
-    @ApiModelProperty("是否公开")
-    boolean isPublic;
-
-    @ApiModelProperty("是否评测")
-    boolean isJudge;
-
-    @ApiModelProperty("是否删除")
-    boolean isDelete;
-
-    @ApiModelProperty("状态")
-    String state;
-}

+ 0 - 1
src/main/java/com/example/onlinejudge/service/QuestionService.java

@@ -6,7 +6,6 @@ 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;
 
 import javax.servlet.http.HttpServletRequest;
 

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

@@ -1,9 +1,8 @@
 package com.example.onlinejudge.service;
 
-import cn.dev33.satoken.util.SaResult;
 import com.example.onlinejudge.model.VO.UserVO;
 import com.example.onlinejudge.model.entity.User;
-import com.example.onlinejudge.model.entity.result.Result;
+import com.example.onlinejudge.common.result.Result;
 
 import javax.servlet.http.HttpServletRequest;
 

+ 1 - 2
src/main/java/com/example/onlinejudge/service/impl/QuestionServiceImpl.java

@@ -10,8 +10,7 @@ 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.User;
-import com.example.onlinejudge.model.entity.result.Result;
-import com.example.onlinejudge.model.entity.result.ResultCode;
+import com.example.onlinejudge.common.result.ResultCode;
 import com.example.onlinejudge.service.QuestionService;
 import com.example.onlinejudge.service.UserService;
 import org.apache.commons.lang3.ObjectUtils;

+ 6 - 3
src/main/java/com/example/onlinejudge/service/impl/QuestionSubmitServiceImpl.java

@@ -12,8 +12,7 @@ import com.example.onlinejudge.model.dto.questionSubmit.QuestionSubmitAddRequest
 import com.example.onlinejudge.model.dto.questionSubmit.QuestionSubmitQueryRequest;
 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.ResultCode;
+import com.example.onlinejudge.common.result.ResultCode;
 import com.example.onlinejudge.model.enums.QuestionSubmitLanguageEnum;
 import com.example.onlinejudge.model.enums.QuestionSubmitStatusEnum;
 import com.example.onlinejudge.service.QuestionService;
@@ -77,14 +76,19 @@ public class QuestionSubmitServiceImpl extends ServiceImpl<QuestionSubmitMapper,
         questionSubmit.setStatus(QuestionSubmitStatusEnum.WAITING.getValue());
         questionSubmit.setJudgeInfo("{}");
         boolean save = this.save(questionSubmit);
+        System.out.println(save);
         if (!save){
             throw new BusinessException(ResultCode.SYSTEM_ERROR, "数据插入失败");
         }
         Long questionSubmitId = questionSubmit.getId();
         // 执行判题服务
+        System.out.println("questionSubmitId = " + questionSubmitId);
         CompletableFuture.runAsync(() -> {
             judgeService.doJudge(questionSubmitId);
         });
+        //TODO: 为什么这里的 q1 是 null
+        QuestionSubmit q1 = this.getById(questionSubmitId);
+        System.out.println(q1.getQuestionId());
         return questionSubmitId;
     }
 
@@ -124,7 +128,6 @@ public class QuestionSubmitServiceImpl extends ServiceImpl<QuestionSubmitMapper,
         QuestionSubmitVO questionSubmitVO = QuestionSubmitVO.objToVo(questionSubmit);
         // 脱敏:仅本人和管理员能看见自己(提交 userId 和登录用户 id 不同)提交的代码
 
-        //TODO 处理脱敏 DONE
         if (userId != questionSubmit.getUserId() && !userService.isAdmin(userId)) {
             questionSubmitVO.setCode(null);
         }

+ 2 - 8
src/main/java/com/example/onlinejudge/service/impl/UserServiceImpl.java

@@ -1,23 +1,17 @@
 package com.example.onlinejudge.service.impl;
 
-import cn.dev33.satoken.exception.NotRoleException;
-import cn.dev33.satoken.stp.SaTokenInfo;
 import cn.dev33.satoken.stp.StpUtil;
-import cn.dev33.satoken.util.SaResult;
-import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.example.onlinejudge.model.VO.UserVO;
 import com.example.onlinejudge.model.entity.User;
 import com.example.onlinejudge.mapper.UserMapper;
-import com.example.onlinejudge.model.entity.result.Result;
-import com.example.onlinejudge.model.entity.result.ResultCode;
+import com.example.onlinejudge.common.result.Result;
+import com.example.onlinejudge.common.result.ResultCode;
 import com.example.onlinejudge.service.UserService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
-import sun.security.krb5.internal.PAData;
 
 import javax.servlet.http.HttpServletRequest;
-import java.util.LinkedHashMap;
 
 /**
  * 实现用户服务

+ 8 - 6
src/main/resources/application.yml

@@ -8,17 +8,17 @@ spring:
       driver-class-name: com.mysql.cj.jdbc.Driver
       url: jdbc:mysql://localhost:3306/oj?useSSL=false&allowPublicKeyRetrieval=true&serverTimeZone=UTC
       username: root
-      password: colin123
+      password: 123456
       max-wait: 3000
       initial-size: 10
       max-active: 200
 
 
-#mybatis:
-#  mapper-locations: classpath:mapper/*.xml
-#  configuration:
-##    开启驼峰映射
-#    map-underscore-to-camel-case: true
+mybatis:
+  mapper-locations: classpath:mapper/*.xml
+  configuration:
+#    开启驼峰映射
+    map-underscore-to-camel-case: true
 
 sa-token:
   # token 名称(同时也是 cookie 名称)
@@ -38,4 +38,6 @@ sa-token:
 
 knife4j:
   enable: true
+codesandbox:
+  type: remote
 

+ 30 - 0
src/main/resources/mapper/QuestionMapper.xml

@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.example.onlinejudge.mapper.QuestionMapper">
+
+    <resultMap id="BaseResultMap" type="com.example.onlinejudge.model.entity.Question">
+            <id property="id" column="id" jdbcType="BIGINT"/>
+            <result property="title" column="title" jdbcType="VARCHAR"/>
+            <result property="content" column="content" jdbcType="VARCHAR"/>
+            <result property="tags" column="tags" jdbcType="OTHER"/>
+            <result property="answer" column="answer" jdbcType="VARCHAR"/>
+            <result property="submitNum" column="submit_num" jdbcType="INTEGER"/>
+            <result property="acceptedNum" column="accepted_num" jdbcType="INTEGER"/>
+            <result property="judgeCase" column="judge_case" jdbcType="OTHER"/>
+            <result property="judgeConfig" column="judge_config" jdbcType="OTHER"/>
+            <result property="userId" column="user_id" jdbcType="BIGINT"/>
+            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
+            <result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
+            <result property="isDelete" column="is_delete" jdbcType="TINYINT"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id,title,content,
+        tags,answer,submit_num,
+        accepted_num,judge_case,judge_config,
+        user_id,create_time,update_time,
+        is_delete
+    </sql>
+</mapper>

+ 30 - 0
src/main/resources/mapper/QuestionSubmitMapper.xml

@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.example.onlinejudge.mapper.QuestionSubmitMapper">
+
+    <resultMap id="BaseResultMap" type="com.example.onlinejudge.model.entity.QuestionSubmit">
+            <id property="id" column="id" jdbcType="BIGINT"/>
+            <result property="language" column="language" jdbcType="VARCHAR"/>
+            <result property="code" column="code" jdbcType="VARCHAR"/>
+            <result property="judgeInfo" column="judge_info" jdbcType="VARCHAR"/>
+            <result property="status" column="status" jdbcType="INTEGER"/>
+            <result property="questionId" column="question_id" jdbcType="BIGINT"/>
+            <result property="userId" column="user_id" jdbcType="BIGINT"/>
+            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
+            <result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
+            <result property="userCases" column="user_cases" jdbcType="VARCHAR"/>
+            <result property="output" column="output" jdbcType="VARCHAR"/>
+            <result property="judgeMode" column="judge_mode" jdbcType="INTEGER"/>
+            <result property="isDelete" column="is_delete" jdbcType="INTEGER"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id,language,code,
+        judge_info,status,question_id,
+        user_id,create_time,update_time,
+        user_cases,output,judge_mode,
+        is_delete
+    </sql>
+</mapper>