Browse Source

Merge branch 'westt/add_submitcode' of rongrunxiang/OnlineJudge into master

rongrunxiang 1 year ago
parent
commit
8d0bfb3407

+ 16 - 34
pom.xml

@@ -37,22 +37,17 @@
             <optional>true</optional>
         </dependency>
 
-        <!-- 数据库相关 -->
-        <dependency>
-            <groupId>mysql</groupId>
-            <artifactId>mysql-connector-java</artifactId>
-            <version>8.0.28</version>
-        </dependency>
-        <dependency>
-            <groupId>org.mybatis.spring.boot</groupId>
-            <artifactId>mybatis-spring-boot-starter</artifactId>
-            <version>2.3.1</version>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring-jdbc</artifactId>
-            <version>5.3.14</version>
-        </dependency>
+<!--         数据库相关 -->
+<!--        <dependency>-->
+<!--            <groupId>mysql</groupId>-->
+<!--            <artifactId>mysql-connector-java</artifactId>-->
+<!--            <version>8.0.28</version>-->
+<!--        </dependency>-->
+<!--        <dependency>-->
+<!--            <groupId>org.springframework</groupId>-->
+<!--            <artifactId>spring-jdbc</artifactId>-->
+<!--            <version>5.3.14</version>-->
+<!--        </dependency>-->
         <dependency>
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-lang3</artifactId>
@@ -62,14 +57,6 @@
             <artifactId>mybatis-plus-boot-starter</artifactId>
             <version>3.5.2</version>
         </dependency>
-
-        <!-- 登陆/权限相关 -->
-        <dependency>
-            <groupId>cn.dev33</groupId>
-            <artifactId>sa-token-spring-boot-starter</artifactId>
-            <version>1.34.0.temp1</version>
-        </dependency>
-
         <!-- 工具类 -->
         <dependency>
             <groupId>org.projectlombok</groupId>
@@ -82,11 +69,6 @@
             <version>5.8.18</version>
         </dependency>
         <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-test</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
             <scope>test</scope>
@@ -100,11 +82,11 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-jdbc</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.mybatis.spring.boot</groupId>
-            <artifactId>mybatis-spring-boot-starter</artifactId>
-            <version>2.1.4</version>
-        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>org.mybatis.spring.boot</groupId>-->
+<!--            <artifactId>mybatis-spring-boot-starter</artifactId>-->
+<!--            <version>2.1.4</version>-->
+<!--        </dependency>-->
         <dependency>
             <groupId>com.mysql</groupId>
             <artifactId>mysql-connector-j</artifactId>

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

@@ -1,10 +1,12 @@
 package com.example.onlinejudge;
 
 import cn.dev33.satoken.SaManager;
+import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 
 @SpringBootApplication
+@MapperScan("com.example.onlinejudge.mapper")
 public class OnlineJudgeApplication {
 
     public static void main(String[] args) {

+ 1 - 1
src/main/java/com/example/onlinejudge/config/SaTokenConfigure.java

@@ -22,7 +22,7 @@ public class SaTokenConfigure implements WebMvcConfigurer {
                 // 指定一条 match 规则
                 SaRouter
                         .match("/**")
-                        .notMatch("/api/login/**")
+                        .notMatch("/api/user/login/**")
                         .check(r -> StpUtil.checkLogin());
         })).addPathPatterns("/**");
     }

+ 15 - 5
src/main/java/com/example/onlinejudge/controller/JudgeController.java

@@ -2,19 +2,21 @@ 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.service.QuestionService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 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 org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
 
 @Api(tags = "提交判题")
 @RestController
-@RequestMapping("/judge")
+@RequestMapping("/api/judge")
 @Slf4j
 public class JudgeController {
+    @Autowired
+    private QuestionService questionService;
 
     @ApiOperation(value = "上传代码进行判题")
     @PostMapping("/insertDataset")
@@ -22,4 +24,12 @@ public class JudgeController {
 
         return Result.success();
     }
+    @PostMapping("/submitCode")
+    public Result submitCode(@RequestParam("code") String code,
+                             @RequestParam("questionId") String questionID,
+                             @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);
+    }
 }

+ 12 - 15
src/main/java/com/example/onlinejudge/controller/UserController.java

@@ -2,17 +2,17 @@ package com.example.onlinejudge.controller;
 
 import cn.dev33.satoken.stp.StpUtil;
 import cn.dev33.satoken.util.SaResult;
+import com.example.onlinejudge.model.entity.result.Result;
 import com.example.onlinejudge.service.UserService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.*;
 
 /**
  * 用户Controller层
  */
 @Controller
+@RequestMapping("/api/user")
 public class UserController {
     @Autowired
     private UserService userService;
@@ -24,10 +24,10 @@ public class UserController {
      * @param password 用户密码
      * @return 用户bean
      */
-    @RequestMapping("/api/login/{username}/{password}")
+    @PostMapping("/login/{username}/{password}")
     @ResponseBody
-    public SaResult login(@PathVariable("username") String username,
-                          @PathVariable("password") String password) {
+    public Result login(@PathVariable("username") String username,
+                        @PathVariable("password") String password) {
         return userService.login(username, password);
     }
 
@@ -36,24 +36,21 @@ public class UserController {
      *
      * @return 字符串
      */
-    @RequestMapping("/api/isLogin")
+    @GetMapping("/isLogin")
     @ResponseBody
     public String isLogin() {
-        return "当前会话是否登录:" + StpUtil.isLogin();
+        return "当前会话登录了";
     }
 
     /**
      * 测试注销
-     *
-     * @return
+     * @return LinkedHashMap
      */
-    @RequestMapping("/api/logout")
+    @GetMapping("/logout")
     @ResponseBody
-    public SaResult logout() {
+    public Result logout() {
         StpUtil.logout();
-        return SaResult
-                .ok()
-                .set("error_message", "success");
+        return Result.success();
     }
 
 }

+ 0 - 20
src/main/java/com/example/onlinejudge/controller/exception/GlobalExceptionHandler.java

@@ -1,20 +0,0 @@
-package com.example.onlinejudge.controller.exception;
-
-import cn.dev33.satoken.exception.NotLoginException;
-import cn.dev33.satoken.util.SaResult;
-import org.springframework.web.bind.annotation.ExceptionHandler;
-import org.springframework.web.bind.annotation.RestControllerAdvice;
-
-/**
- * 全局拦截异常
- */
-@RestControllerAdvice
-public class GlobalExceptionHandler {
-    @ExceptionHandler(NotLoginException.class)
-    public SaResult handlerException(NotLoginException e) {
-        e.printStackTrace();
-        return SaResult
-                .error(e.getMessage())
-                .set("error_message", "failed");
-    }
-}

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

@@ -0,0 +1,25 @@
+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 org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+/**
+ * 全局拦截异常
+ */
+@RestControllerAdvice
+public class GlobalExceptionHandler {
+    /**
+     * 拦截未登录的用户进行非法权限操作
+     * @param e NotLoginException
+     * @return 返回未登录错误
+     */
+    @ExceptionHandler(NotLoginException.class)
+    public Result handlerException(NotLoginException e) {
+        e.printStackTrace();
+        return Result.error(ResultCode.USER_NOTLOGGED_IN);
+    }
+}

+ 9 - 0
src/main/java/com/example/onlinejudge/mapper/QuestionSubmitMapper.java

@@ -0,0 +1,9 @@
+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
+public interface QuestionSubmitMapper extends BaseMapper<QuestionSubmit> {
+}

+ 3 - 1
src/main/java/com/example/onlinejudge/mapper/UserMapper.java

@@ -1,10 +1,12 @@
 package com.example.onlinejudge.mapper;
 
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.example.onlinejudge.model.entity.User;
 import org.apache.ibatis.annotations.Mapper;
 
 @Mapper
-public interface UserMapper {
+public interface UserMapper extends BaseMapper<User> {
     User selectUserById(Integer id);
     User selectUserByUsernameAndPassword(String username, String password);
+    boolean insertUser(String username, String password);
 }

+ 19 - 0
src/main/java/com/example/onlinejudge/model/entity/QuestionSubmit.java

@@ -1,7 +1,10 @@
 package com.example.onlinejudge.model.entity;
 
 import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.AllArgsConstructor;
 import lombok.Data;
+import lombok.NoArgsConstructor;
 
 import java.util.Date;
 
@@ -10,6 +13,8 @@ import java.util.Date;
  */
 @TableName(value ="question_submit")
 @Data
+@AllArgsConstructor
+@NoArgsConstructor
 public class QuestionSubmit {
     /**
      * id
@@ -58,6 +63,20 @@ public class QuestionSubmit {
     private Date updateTime;
 
     /**
+     * 用户自测用例
+     */
+    private String userCases;
+
+    /**
+     * 用户自测用例的输出
+     */
+    private String output;
+    /**
+     * 判断模式 (0 - 系统用例判别 1 - 用户自测用例判别)
+     */
+    private Integer judgeMode;
+
+    /**
      * 是否删除
      */
     @TableLogic

+ 7 - 2
src/main/java/com/example/onlinejudge/model/entity/User.java

@@ -1,5 +1,9 @@
 package com.example.onlinejudge.model.entity;
 
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
@@ -10,12 +14,13 @@ import java.util.List;
 /**
  * 用户bean
  */
+@TableName("user")
 @Data
 @AllArgsConstructor
 @NoArgsConstructor
 public class User {
-    private Integer id;
+    @TableId(type = IdType.AUTO)
+    private Long id;
     private String username;
     private String password;
-    private Timestamp registerTime;
 }

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

@@ -1,4 +1,24 @@
 package com.example.onlinejudge.service;
 
+import com.example.onlinejudge.model.entity.result.Result;
+
 public interface QuestionService {
+    /**
+     * 接受用户提交的解决方案
+     * @param questionID 问题id
+     * @param code 用户提交的代码
+     * @param language 使用的语言
+     * @param userCases 用户自测用例
+     * @param judgeMode 判断模式
+     * @return
+     */
+    Result receiveCode(Long questionID, String code, String language, String userCases, Integer judgeMode);
+
+    /**
+     * 判断本次用户提交的解决方案是否合法
+     * @param userId 用户id
+     * @param questionID wentiid
+     * @return
+     */
+    boolean checkIsSubmitValid(Long userId, Long questionID);
 }

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

@@ -1,8 +1,8 @@
 package com.example.onlinejudge.service;
 
 import cn.dev33.satoken.util.SaResult;
+import com.example.onlinejudge.model.entity.result.Result;
 
 public interface UserService {
-    SaResult login(String username, String password);
-    String register(String username, String password, String confirmedPassword);
+    Result login(String username, String password);
 }

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

@@ -1,4 +1,86 @@
 package com.example.onlinejudge.service.impl;
 
-public class QuestionServiceImpl {
+import cn.dev33.satoken.stp.StpUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.example.onlinejudge.mapper.QuestionSubmitMapper;
+import com.example.onlinejudge.model.entity.QuestionSubmit;
+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 org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Date;
+
+
+@Service
+public class QuestionServiceImpl implements QuestionService {
+    @Autowired
+    private QuestionSubmitMapper questionSubmitMapper;
+
+    @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(), "空或未知的编程语言");
+        }
+        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);
+        }
+        questionSubmitMapper.insert(questionSubmit);
+        System.out.println(questionSubmit);
+        // TODO: 1.提交代码到判题系统 2.更改数据库刷新状态 3.返回判题信息
+        return Result.success();
+    }
+
+    @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;
+    }
 }

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

@@ -1,12 +1,20 @@
 package com.example.onlinejudge.service.impl;
 
+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.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.service.UserService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import sun.security.krb5.internal.PAData;
+
+import java.util.LinkedHashMap;
 
 /**
  * 实现用户服务
@@ -18,22 +26,23 @@ public class UserServiceImpl implements UserService {
 
     /**
      * 用户登录服务
+     *
      * @param username 用户名
      * @param password 密码
      * @return 登录结果
      */
     @Override
-    public SaResult login(String username, String password) {
-        User user = userMapper.selectUserByUsernameAndPassword(username, password);
+    public Result login(String username, String password) {
+        if (StrUtil.isBlank(username) || StrUtil.isBlank(password))
+            return Result.error(ResultCode.PARAM_IS_BLANK.getCode(), "用户名或密码不能为空");
+        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("username", username).eq("password", password);
+        User user = userMapper.selectOne(queryWrapper);
         if (user != null) {
             StpUtil.login(user.getId());
-            return SaResult.ok("success").set("error_message", "success");
+            return Result.success();
         }
-        return SaResult.ok("failed").set("error_message", "用户名或密码错误");
+        return Result.error(ResultCode.USER_LOGIN_ERROR);
     }
 
-    @Override
-    public String register(String username, String password, String confirmedPassword) {
-        return null;
-    }
 }

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

@@ -6,18 +6,19 @@ spring:
     type: com.alibaba.druid.pool.DruidDataSource
     druid:
       driver-class-name: com.mysql.cj.jdbc.Driver
-      url: jdbc:mysql://localhost:3306/testjdbc?useSSL=false&allowPublicKeyRetrieval=true&serverTimeZone=UTC
+      url: jdbc:mysql://localhost:3306/oj?useSSL=false&allowPublicKeyRetrieval=true&serverTimeZone=UTC
       username: root
       password: colin123
       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 名称)

+ 3 - 0
src/main/resources/mapper/userMapper.xml

@@ -9,4 +9,7 @@
     <select id="selectUserByUsernameAndPassword" resultType="com.example.onlinejudge.model.entity.User">
         SELECT * FROM t_user WHERE username = #{param1} and password = #{param2}
     </select>
+    <insert id="insertUser">
+        INSERT INTO t_user VALUES(NULL, #{param1}, #{param2}, NOW())
+    </insert>
 </mapper>