Browse Source

feat: 判题、新建题目

haha 4 years ago
parent
commit
c75e1c2109

+ 28 - 0
seec-oj-server/pom.xml

@@ -71,7 +71,35 @@
             <artifactId>PaasMonitor-client</artifactId>
             <version>0.1.2</version>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.data</groupId>
+            <artifactId>spring-data-jpa</artifactId>
+            <version>2.3.4.RELEASE</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.mybatis</groupId>
+            <artifactId>mybatis-spring</artifactId>
+            <version>2.0.2</version>
+        </dependency>
 
+        <dependency>
+            <groupId>org.mapstruct</groupId>
+            <artifactId>mapstruct</artifactId>
+            <version>1.4.2.Final</version>
+        </dependency>
+        <dependency>
+            <groupId>org.mapstruct</groupId>
+            <artifactId>mapstruct-processor</artifactId>
+            <version>1.4.2.Final</version>
+        </dependency>
 
     </dependencies>
 

+ 1 - 2
seec-oj-server/src/main/java/cn/seecoder/ojserver/controller/JudgeController.java

@@ -6,7 +6,6 @@ import cn.seecoder.ojserver.web.Response;
 import com.nju.edu.paasMonitorClient.MonitorClient;
 import com.nju.edu.paasMonitorClient.entity.Call;
 import com.nju.edu.paasMonitorCommon.enums.SeecSystem;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
 @RestController
@@ -24,7 +23,7 @@ public class JudgeController {
     }
 
     @PostMapping("/code")
-    public Response judgeCode(@RequestParam(value = "questionId") String questionId, @RequestBody CodeJudgeVO codeJudgeVO) {
+    public Response judgeCode(@RequestParam(value = "questionId") Integer questionId, @RequestBody CodeJudgeVO codeJudgeVO) {
         Call call = MonitorClient.createCall(SeecSystem.CODER,"ojtest","/api/judge/code");
         call.start();
         Response res = Response.buildSuccess(judgeService.judgeCode(questionId, codeJudgeVO));

+ 25 - 0
seec-oj-server/src/main/java/cn/seecoder/ojserver/controller/ProblemController.java

@@ -0,0 +1,25 @@
+package cn.seecoder.ojserver.controller;
+
+import cn.seecoder.ojserver.model.vo.ProblemVO;
+import cn.seecoder.ojserver.service.ProblemService;
+import cn.seecoder.ojserver.web.Response;
+import org.springframework.beans.factory.annotation.Autowired;
+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;
+
+@RestController
+@RequestMapping(path = "/api/problem")
+public class ProblemController {
+    private final ProblemService problemService;
+
+    public ProblemController(ProblemService problemService) {
+        this.problemService = problemService;
+    }
+
+    @PostMapping("")
+    public Response create(@RequestBody ProblemVO problemVO){
+        return Response.buildSuccess(this.problemService.create(problemVO));
+    }
+}

+ 10 - 0
seec-oj-server/src/main/java/cn/seecoder/ojserver/dao/ProblemDAO.java

@@ -0,0 +1,10 @@
+package cn.seecoder.ojserver.dao;
+
+import cn.seecoder.ojserver.dao.entity.Problem;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface ProblemDAO extends JpaRepository<Problem,Integer> {
+    Problem findById(int id);
+
+
+}

+ 44 - 0
seec-oj-server/src/main/java/cn/seecoder/ojserver/dao/entity/Problem.java

@@ -0,0 +1,44 @@
+package cn.seecoder.ojserver.dao.entity;
+
+import lombok.Data;
+import org.hibernate.annotations.CreationTimestamp;
+
+import javax.persistence.*;
+import java.util.Date;
+
+@Data
+@Entity
+@Table(name = "problem")
+public class Problem {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Column(name = "id")
+    private Integer id;
+
+    @Basic
+    @Column(name = "description")
+    private String description;
+
+    // MS
+    @Basic
+    @Column(name = "timeLimit")
+    private Integer timeLimit;
+
+    // KB
+    @Basic
+    @Column(name = "memoryLimit")
+    private Integer memoryLimit;
+
+    @Basic
+    @Column(name = "createTime")
+    private Date createTime;
+
+    @Basic
+    @Column(name = "modifiedTime")
+    private Date modifiedTime;
+
+
+
+
+
+}

+ 27 - 0
seec-oj-server/src/main/java/cn/seecoder/ojserver/dao/entity/TestCase.java

@@ -0,0 +1,27 @@
+package cn.seecoder.ojserver.dao.entity;
+
+import lombok.Data;
+
+import javax.persistence.*;
+
+@Data
+@Entity
+@Table(name = "problem_test_cases")
+public class TestCase {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Column(name = "id")
+    private Integer id;
+
+    @Basic
+    @Column(name = "input")
+    private String input;
+
+    @Basic
+    @Column(name = "output")
+    private String output;
+
+    @ManyToOne(targetEntity = Problem.class, fetch = FetchType.LAZY)
+    @JoinColumn(name = "problemId", referencedColumnName = "id")
+    private Problem problem;
+}

+ 11 - 0
seec-oj-server/src/main/java/cn/seecoder/ojserver/dao/entity/TestCaseDAO.java

@@ -0,0 +1,11 @@
+package cn.seecoder.ojserver.dao.entity;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+
+public interface TestCaseDAO extends JpaRepository<TestCase,Integer> {
+    List<TestCase> findAllByProblem(Problem problem);
+
+    List<TestCase> findByProblem_Id(Integer problemId);
+}

+ 22 - 1
seec-oj-server/src/main/java/cn/seecoder/ojserver/manager/QuestionManager.java

@@ -1,18 +1,31 @@
 package cn.seecoder.ojserver.manager;
 
+import cn.seecoder.ojserver.dao.ProblemDAO;
+import cn.seecoder.ojserver.dao.entity.Problem;
+import cn.seecoder.ojserver.dao.entity.TestCase;
+import cn.seecoder.ojserver.dao.entity.TestCaseDAO;
 import cn.seecoder.ojserver.exception.ThirdPartyServiceException;
 import cn.seecoder.ojserver.model.vo.CompleteQuestionVO;
 import cn.seecoder.ojserver.utils.thirdparty.QuestionThirdPartyService;
 import org.springframework.stereotype.Service;
 
+import java.util.List;
 import java.util.Optional;
 
 @Service
 public class QuestionManager {
     private final QuestionThirdPartyService questionThirdPartyService;
 
-    public QuestionManager(QuestionThirdPartyService questionThirdPartyService) {
+    private final ProblemDAO problemDAO;
+
+    private final TestCaseDAO testCaseDAO;
+
+    public QuestionManager(QuestionThirdPartyService questionThirdPartyService,
+                           ProblemDAO problemDAO,
+                           TestCaseDAO testCaseDAO) {
         this.questionThirdPartyService = questionThirdPartyService;
+        this.problemDAO = problemDAO;
+        this.testCaseDAO = testCaseDAO;
     }
 
     public Optional<CompleteQuestionVO> getQuestionById(String id) {
@@ -23,4 +36,12 @@ public class QuestionManager {
             return res;
         }
     }
+
+    public Optional<Problem> getProblemById(Integer id){
+        return problemDAO.findById(id);
+    }
+
+    public List<TestCase> getTestCaseByProblemId(Integer problemId){
+        return testCaseDAO.findByProblem_Id(problemId);
+    }
 }

+ 16 - 0
seec-oj-server/src/main/java/cn/seecoder/ojserver/mapper/ProblemMapper.java

@@ -0,0 +1,16 @@
+package cn.seecoder.ojserver.mapper;
+
+import cn.seecoder.ojserver.dao.entity.Problem;
+import cn.seecoder.ojserver.model.vo.ProblemVO;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+@Mapper(componentModel = "spring")
+public interface ProblemMapper {
+    ProblemMapper INSTANCE = Mappers.getMapper(ProblemMapper.class);
+
+    ProblemVO toVO(Problem problem);
+
+    Problem toPO(ProblemVO problemVO);
+
+}

+ 26 - 0
seec-oj-server/src/main/java/cn/seecoder/ojserver/model/vo/ProblemVO.java

@@ -0,0 +1,26 @@
+package cn.seecoder.ojserver.model.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class ProblemVO {
+    private Integer id;
+
+    private String description;
+
+    /**
+     * 代码题目时间限制 MS
+     */
+    private Integer timeLimit;
+
+    /**
+     * 代码空间限制 KB
+     */
+    private Integer memoryLimit;
+}

+ 1 - 1
seec-oj-server/src/main/java/cn/seecoder/ojserver/service/JudgeService.java

@@ -4,5 +4,5 @@ import cn.seecoder.codejudge.client.JudgeResult;
 import cn.seecoder.ojserver.model.vo.CodeJudgeVO;
 
 public interface JudgeService {
-    public JudgeResult judgeCode(String questionId, CodeJudgeVO codeJudgeVO);
+    public JudgeResult judgeCode(Integer questionId, CodeJudgeVO codeJudgeVO);
 }

+ 8 - 0
seec-oj-server/src/main/java/cn/seecoder/ojserver/service/ProblemService.java

@@ -0,0 +1,8 @@
+package cn.seecoder.ojserver.service;
+
+import cn.seecoder.ojserver.dao.entity.Problem;
+import cn.seecoder.ojserver.model.vo.ProblemVO;
+
+public interface ProblemService {
+    public ProblemVO create(ProblemVO problemVO);
+}

+ 17 - 6
seec-oj-server/src/main/java/cn/seecoder/ojserver/service/impl/JudgeServiceImpl.java

@@ -2,14 +2,16 @@ package cn.seecoder.ojserver.service.impl;
 
 import cn.seecoder.codejudge.client.JudgeDTO;
 import cn.seecoder.codejudge.client.JudgeResult;
+import cn.seecoder.ojserver.dao.entity.Problem;
+import cn.seecoder.ojserver.dao.entity.TestCase;
 import cn.seecoder.ojserver.exception.ThirdPartyServiceException;
 import cn.seecoder.ojserver.manager.JudgeManager;
 import cn.seecoder.ojserver.manager.QuestionManager;
 import cn.seecoder.ojserver.model.vo.CodeJudgeVO;
-import cn.seecoder.ojserver.model.vo.CompleteQuestionVO;
 import cn.seecoder.ojserver.service.JudgeService;
 import org.springframework.stereotype.Service;
 
+import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
 
@@ -24,16 +26,25 @@ public class JudgeServiceImpl implements JudgeService {
     }
 
     @Override
-    public JudgeResult judgeCode(String questionId, CodeJudgeVO codeJudgeVO) {
+    public JudgeResult judgeCode(Integer questionId, CodeJudgeVO codeJudgeVO) {
         try {
             JudgeDTO judgeDTO = new JudgeDTO();
             judgeDTO.setCode(codeJudgeVO.getCode());
             judgeDTO.setLanguage(codeJudgeVO.getLanguage());
 
-            CompleteQuestionVO question = questionManager.getQuestionById(questionId).get();
-            judgeDTO.setMemoryLimit(question.getMemoryLimit());
-            judgeDTO.setInputList(question.getInputOutputMapping().entrySet().stream().map(Map.Entry<String, String>::getKey).collect(Collectors.toList()));
-            judgeDTO.setOutputList(question.getInputOutputMapping().entrySet().stream().map(Map.Entry<String, String>::getValue).collect(Collectors.toList()));
+            Problem problem = questionManager.getProblemById(questionId).get();
+            List<TestCase> testCaseList = questionManager.getTestCaseByProblemId(questionId);
+            judgeDTO.setMemoryLimit(problem.getMemoryLimit());
+            judgeDTO.setTimeLimit(problem.getTimeLimit());
+            List<String> inputList = testCaseList.stream().map(TestCase::getInput).collect(Collectors.toList());
+            System.out.println(inputList);
+            List<String> outputList = testCaseList.stream().map(TestCase::getOutput).collect(Collectors.toList());
+            System.out.println(outputList);
+            judgeDTO.setInputList(inputList);
+            judgeDTO.setOutputList(outputList);
+//            judgeDTO.setInputList(question.getInputOutputMapping().entrySet().stream().map(Map.Entry<String, String>::getKey).collect(Collectors.toList()));
+//            judgeDTO.setOutputList(question.getInputOutputMapping().entrySet().stream().map(Map.Entry<String, String>::getValue).collect(Collectors.toList()));
+
 
             return judgeManager.judgeCodeQuestionAnswers(judgeDTO);
         } catch (ThirdPartyServiceException exception) {

+ 30 - 0
seec-oj-server/src/main/java/cn/seecoder/ojserver/service/impl/ProblemServiceImpl.java

@@ -0,0 +1,30 @@
+package cn.seecoder.ojserver.service.impl;
+
+import cn.seecoder.ojserver.dao.ProblemDAO;
+import cn.seecoder.ojserver.dao.entity.Problem;
+import cn.seecoder.ojserver.mapper.ProblemMapper;
+import cn.seecoder.ojserver.model.vo.ProblemVO;
+import cn.seecoder.ojserver.service.ProblemService;
+import org.springframework.stereotype.Service;
+
+import java.util.Date;
+
+@Service
+public class ProblemServiceImpl implements ProblemService {
+
+    private final ProblemDAO problemDAO;
+
+    public ProblemServiceImpl(ProblemDAO problemDAO) {
+        this.problemDAO = problemDAO;
+    }
+
+    @Override
+    public ProblemVO create(ProblemVO problemVO) {
+        Problem problem = ProblemMapper.INSTANCE.toPO(problemVO);
+        problem.setCreateTime(new Date());
+        problem.setModifiedTime(new Date());
+        System.out.println(problem);
+        this.problemDAO.save(problem);
+        return ProblemMapper.INSTANCE.toVO(problem);
+    }
+}

+ 12 - 1
seec-oj-server/src/main/resources/application-prod.yml

@@ -1,6 +1,17 @@
 server:
   port: 8080
-
+spring:
+  datasource:
+    url: jdbc:mysql://localhost:3306/coder_oj?useUnicode=true&characterEncoding=UTF-8&useSSL=false
+    username: root
+    password: root
+    driver-class-name: com.mysql.cj.jdbc.Driver
+  jpa:
+    hibernate:
+      naming:
+        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
+      ddl-auto: update
+    show-sql: false
 seec-bok-client:
   host: https://bok.seec.seecoder.cn