项目重构,添加评测,判题服务模块

This commit is contained in:
Himit_ZH 2020-10-30 23:54:48 +08:00
parent 09c4f131cc
commit d86c1e11bd
341 changed files with 12735 additions and 127 deletions

268
README.md
View File

@ -10,18 +10,17 @@
| ---------- | ------------------------------------------------------ | -------- |
| 2020-10-26 | 数据库设计,登录和注册接口,文档记录开始。 | Himit_ZH |
| 2020-10-28 | 用户模块接口,题目模块接口,比赛模块接口,排行模块接口 | Himit_ZH |
| 2020-10-30 | 评测模块接口判题服务系统初始化前端vue项目 | Himit_ZH |
# 二、系统架构
> 总概大系统
> 总概大系统
1. 前端vue页面显示系统电脑端手机端
2. 数据交互后台系统
3. 判题后台系统
4. 判题机系统
4. 判题服务系统
5. 爬虫系统
@ -33,9 +32,28 @@
1. 前端提交数据。
2. 后端数据交互后台微服务将提交写入数据库使用springcloud alibaba通过nacos注册中心调用判题后台系统微服务。
3. 判题后台系统微服务使用RabbitMQ告知判题机系统传递submitId集合) 。
4. 判题机系统启用多台判题机(多个进程,有限,防宕机)进行测评,最后将结果更新到数据库。
5. 爬虫系统负责爬取用户相关的codeforces的积分vjudge的做题数等。
3. 判题后台系统微服务,启用多台判题机(多个进程,有限,防宕机)进行测评,最后将结果更新到数据库。
4. 爬虫系统负责爬取用户相关的codeforces的积分vjudge的做题数等。
> HOJ基本逻辑架构图
![image-20201030234527577](.\md-images\hoj.png)
> springcloud alibaba 分布式微服务架构图
>
> Consumer后台数据交互服务
>
> Provider判题服务
>
> Nacos注册中心Consumer通过nacos调用Provider
![](.\md-images\spingcloud-Alibaba.png)
# 三、数据库
@ -195,44 +213,49 @@ problem_count表
> 判题结果status
STATUS_ACCPET = 0
排队中STATUS_QUEUING = -10
STATUS__WRONG_ANSWER = -1
判题中 STATUS_JUDGING = -5
STATUS__CPU_TIME_LIMIT_EXCEEDED = 1
通过STATUS_ACCPET = 0
STATUS__REAL_TIME_LIMIT_EXCEEDED = 2
答案错误STATUS__WRONG_ANSWER = -1
STATUS__MEMORY_LIMIT_EXCEEDED = 3
cpu时间超限STATUS__CPU_TIME_LIMIT_EXCEEDED = 1
STATUS__RUNTIME_ERROR = 4
真实时间超限STATUS__REAL_TIME_LIMIT_EXCEEDED = 2
STATUS__SYSTEM_ERROR = 5
空间超限STATUS__MEMORY_LIMIT_EXCEEDED = 3
运行错误STATUS__RUNTIME_ERROR = 4
系统错误STATUS__SYSTEM_ERROR = 5
judge表
| 列名 | 实体属性类型 | 键 | 备注 |
| ------------ | ------------ | ----------- | ---------------------------------- |
| submit_id | long | primary key | auto_increment |
| pid | long | 外键 | 题目id |
| uid | String | 外键 | 提交用户的id |
| submit_time | datetime | | 提交时间 |
| status | String | | 判题结果 |
| auth | int | | 0为代码全部人可见1为仅自己可见。 |
| error_message| String | | 错误提醒编译错误或者vj提醒 |
| time | int | | 运行时间 |
| memory | int | | 所耗内存 |
| length | int | | 代码长度 |
| code | String | | 代码 |
| language | String | | 代码语言 |
| cpid | int | | 比赛中的题目编号id |
| judger | String | | 判题机ip |
| ip | String | | 提交者ip |
| cid | int | | 题目来源的比赛id默认为0 |
| gmt_create | datetime | | 创建时间 |
| gmt_modified | datetime | | 修改时间 |
| 列名 | 实体属性类型 | 键 | 备注 |
| ------------- | ------------ | ----------- | ---------------------------------- |
| submit_id | long | primary key | auto_increment |
| pid | long | 外键 | 题目id |
| uid | String | 外键 | 提交用户的id |
| submit_time | datetime | | 提交时间 |
| status | String | | 判题结果 |
| auth | int | | 0为代码全部人可见1为仅自己可见。 |
| error_message | String | | 错误提醒编译错误或者vj提醒 |
| time | int | | 运行时间 |
| memory | int | | 所耗内存 |
| length | int | | 代码长度 |
| code | String | | 代码 |
| language | String | | 代码语言 |
| cpid | int | | 比赛中的题目编号id |
| judger | String | | 判题机ip |
| ip | String | | 提交者ip |
| cid | int | | 题目来源的比赛id默认为0 |
| version | int | | 乐观锁 |
| gmt_create | datetime | | 创建时间 |
| gmt_modified | datetime | | 修改时间 |
@ -289,15 +312,14 @@ contest表
contest_problem表
| 列名 | 实体属性类型 | 键 | 备注 |
| ------------ | ------------ | ----------- | ---------------------- |
| id | long | 主键 | auto_increment |
| cid | int | 外键 | 比赛id |
| pid | int | 外键 | 题目id |
| cp_name | String | | 用于当场比赛的题目标题 |
| cp_num | String | | 比赛题目的顺序id |
| gmt_create | datetime | | 创建时间 |
| gmt_modified | datetime | | 修改时间 |
| 列名 | 实体属性类型 | 键 | 备注 |
| ------------ | ------------ | ---- | ---------------------- |
| id | long | 主键 | auto_increment |
| cid | int | 外键 | 比赛id |
| pid | int | 外键 | 题目id |
| cp_name | String | | 用于当场比赛的题目标题 |
| gmt_create | datetime | | 创建时间 |
| gmt_modified | datetime | | 修改时间 |
@ -408,7 +430,7 @@ comment_tag表 讨论标签表
# 四、后端数据接口
# 四、后端交互系统
@ -893,4 +915,160 @@ data数据
| submissions | int | 总提交数 |
| ac | int | 总通过数 |
| Rating | int | cf得分 |
| score | int | io制比赛得分 |
| score | int | io制比赛得分 |
### (五)、评测模块
> 评测分为普通做题评测和比赛做题评测
#### 1. 提交评测接口
##### 1.1 请求地址
> /api/submit-problem-judge
##### 1.2 请求方式
> POST
**需要做登录授权认证!**
##### 1.3 请求参数
> 格式json
| 字段名 | 实体属性类型 | 说明 | 能否为空 |
| -------- | ------------ | -------------------------------- | -------- |
| pid | long | 题目id | 不能 |
| uid | String | 用户id | 不能 |
| language | String | 代码语言 | 不能 |
| code | String | 代码 | 不能 |
| auth | int | 0为代码全部人可见1为仅自己可见 | 不能 |
| cid | long | 所属比赛id若无设置为0 | 不能 |
| cpid | long | 所属比赛题目id若无设置为0 | 不能 |
##### 1.4 返回数据
> 格式json
| 字段名 | 实体属性类型 | 说明 |
| ------ | ------------ | ---------------------------------- |
| status | int | 状态码,详情见状态码说明 |
| data | json | 评测结果具体看Judge类或judge表 |
| msg | String | 消息 |
#### 2. 评测列表接口
##### 2.1 请求地址
> /api/get-judge-list
##### 2.2 请求方式
> GET
##### 2.3 请求参数
> 格式x-www-form-urlencoded
| 字段名 | 实体属性类型 | 说明 | 能否为空 |
| -------------- | ------------ | -------------------------------------------- | -------- |
| limit | String | (查询条件)每页的判题条数 | 能 |
| currentPage | int | (查询条件)页数 | 能 |
| searchPid | long | 查询条件题目id | 能 |
| searchSource | String | (查询条件)题目来源 | 能 |
| searchLanguage | String | (查询条件)提交代码语言 | 能 |
| searchStatus | int | (查询条件)提交代码结果 | 能 |
| searchUsername | String | (查询条件)提交的用户名 | 能 |
| searchCid | long | 比赛评测状态根据cid若非比赛的则设置为0即可 | 不能 |
##### 2.4 返回数据
> 格式json
| 字段名 | 实体属性类型 | 说明 |
| ------ | ------------ | --------------------------------- |
| status | int | 状态码,详情见状态码说明 |
| data | json | 判题结果列表具体请看JudgeVo类 |
| msg | String | 消息 |
#### 3. 评测样例接口
##### 1.1 请求地址
> /api/get-judge-case
##### 1.2 请求方式
> GET
##### 1.3 请求参数
> 格式x-www-form-urlencoded
| 字段名 | 实体属性类型 | 说明 | 能否为空 |
| -------- | ------------ | ------ | -------- |
| submitId | long | 提交id | 不能 |
| pid | long | 题目id | 不能 |
##### 1.4 返回数据
> 格式json
| 字段名 | 实体属性类型 | 说明 |
| ------ | ------------ | ----------------------------------------- |
| status | int | 状态码,详情见状态码说明 |
| data | json | 评测样例列表JudgeCase类或judge_case表 |
| msg | String | 消息 |
### (六)、讨论模块
> 暂时搁置,可能自己写,也可能用别人的组件!!!!
#####
# 五、判题服务系统
### (一)、数据接口模块
> 后端数据交互系统在nacos注册中心通过openfeign的形式调用判题系统服务
#### 1. 评测接口
##### 1.1 请求地址
> /judge
##### 1.2 请求方式
> POST
##### 1.3 请求参数
> 格式json
| 字段名 | 实体属性类型 | 说明 | 能否为空 |
| -------- | ------------ | -------------------------------- | -------- |
| pid | long | 题目id | 不能 |
| uid | String | 用户id | 不能 |
| language | String | 代码语言 | 不能 |
| code | String | 代码 | 不能 |
| auth | int | 0为代码全部人可见1为仅自己可见 | 不能 |
| cid | long | 所属比赛id若无设置为0 | 不能 |
| cpid | long | 所属比赛题目id若无设置为0 | 不能 |
##### 1.4 返回数据
> 格式json
| 字段名 | 实体属性类型 | 说明 |
| ------ | ------------ | ---------------------------------- |
| status | int | 状态码,详情见状态码说明 |
| data | json | 评测结果具体看Judge类或judge表 |
| msg | String | 消息 |
###(二)、判题机模块

View File

@ -7,6 +7,7 @@
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="DataBackup" />
<module name="JudgeServer" />
<module name="api" />
</profile>
</annotationProcessing>

View File

@ -3,7 +3,7 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>hoj</artifactId>
<artifactId>hoj-springboot</artifactId>
<groupId>top.hcode</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
@ -44,14 +44,19 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.alibaba.cloud</groupId>-->
<!-- <artifactId>spring-cloud-alibaba-nacos-discovery</artifactId>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.springframework.cloud</groupId>-->
<!-- <artifactId>spring-cloud-starter-openfeign</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--服务熔断,降级,限流的哨兵-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>

View File

@ -2,6 +2,8 @@ package top.hcode.hoj;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.scheduling.annotation.EnableAsync;
/**
@ -9,9 +11,9 @@ import org.springframework.scheduling.annotation.EnableAsync;
* @Date: 2020/10/22 23:25
* @Description:
*/
//@EnableDiscoveryClient
@EnableDiscoveryClient
@SpringBootApplication
//@EnableFeignClients
@EnableFeignClients // 开启feign
@EnableAsync //开启异步注解
public class DataBackupApplication {
public static void main(String[] args) {

View File

@ -0,0 +1,23 @@
package top.hcode.hoj.common.exception;
import org.springframework.stereotype.Component;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.entity.Judge;
import top.hcode.hoj.service.ToJudgeService;
/**
* @Author: Himit_ZH
* @Date: 2020/10/30 10:21
* @Description:
*/
@Component
public class CloudHandler implements ToJudgeService {
@Override
public CommonResult submitProblemJudge(Judge judge) {
return CommonResult.errorResponse("判题机系统出错,提交进入重判队列,请等待管理员处理!", CommonResult.STATUS_ERROR);
}
}

View File

@ -37,7 +37,7 @@ public class CommonResult implements Serializable {
* 成功的结果
* @param data 返回结果
*/
public CommonResult successResponse(Object data) {
public static CommonResult successResponse(Object data) {
return new CommonResult(CommonResult.STATUS_SUCCESS, data, null);
}

View File

@ -0,0 +1,20 @@
package top.hcode.hoj.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* @Author: Himit_ZH
* @Date: 2020/10/29 22:49
* @Description:
*/
@Configuration
public class CloudConfig {
@Bean
@LoadBalanced //设置实现负载均衡Ribbon
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}

View File

@ -1,4 +1,5 @@
package top.hcode.hoj.config;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
@ -15,6 +16,11 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
@MapperScan("top.hcode.hoj.dao")
public class MybatisPlusConfig {
// 注册乐观锁插件
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
// 分页插件
@Bean

View File

@ -5,10 +5,10 @@ import org.springframework.web.bind.annotation.RestController;
/**
* @Author: Himit_ZH
* @Date: 2020/10/27 20:52
* @Description: 处理代码评判
* @Date: 2020/10/29 10:14
* @Description:
*/
@RestController
@RequestMapping("/api")
public class JudgeController {
public class CommentController {
}

View File

@ -96,7 +96,7 @@ public class ContestController {
@GetMapping("/get-contest-problem")
public CommonResult getContestProblem(@RequestParam(value = "cid",required = true) Long cid){
QueryWrapper<ContestProblem> wrapper = new QueryWrapper<ContestProblem>().eq("cid", cid)
.orderByAsc("cp_num");
.orderByAsc("id");
List<ContestProblem> contestProblemList = contestProblemMapper.selectList(wrapper);
if (contestProblemList.size()==0) {

View File

@ -0,0 +1,159 @@
package top.hcode.hoj.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.dao.JudgeCaseMapper;
import top.hcode.hoj.dao.JudgeMapper;
import top.hcode.hoj.pojo.dto.ToJudgeDto;
import top.hcode.hoj.pojo.entity.Judge;
import top.hcode.hoj.pojo.entity.JudgeCase;
import top.hcode.hoj.pojo.entity.Problem;
import top.hcode.hoj.pojo.vo.JudgeVo;
import top.hcode.hoj.service.JudgeService;
import top.hcode.hoj.service.ProblemService;
import top.hcode.hoj.service.ToJudgeService;
import top.hcode.hoj.utils.IpUtils;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
/**
* @Author: Himit_ZH
* @Date: 2020/10/27 20:52
* @Description: 处理代码评判相关业务
*/
@RestController
@RequestMapping("/api")
public class JudgeController {
@Autowired
private JudgeService judgeService;
@Autowired
private JudgeMapper judgeMapper;
@Autowired
private JudgeCaseMapper judgeCaseMapper;
@Autowired
private ProblemService problemService;
@Autowired
private ToJudgeService toJudgeService;
// @Autowired
// private RestTemplate restTemplate;
// @Value("${service-url.hoj-judge-server}") // restTemplate风格调用不使用
// private String REST_URL_PREFIX;
// @GetMapping("/submit-problem-judge")
// public String list(){
// return restTemplate.getForObject(REST_URL_PREFIX+"/hoj-judge-server/submit-problem-judge", String.class);
// }
/**
* @MethodName submitProblemJudge
* @Params * @param null
* @Description 核心方法 判题通过openfeign调用判题系统服务
* @Return CommonResult
* @Since 2020/10/30
*/
@RequiresAuthentication
@RequestMapping(value = "/submit-problem-judge",method = RequestMethod.POST)
public CommonResult submitProblemJudge(@RequestBody ToJudgeDto judgeDto, HttpServletRequest request){
// 将提交先写入数据库准备调用判题服务器
Judge judge = new Judge();
int result = judgeMapper.insert(judge.setAuth(judgeDto.getAuth())
.setCid(judgeDto.getCid())
.setCode(judgeDto.getCode())
.setCpid(judgeDto.getCpid())
.setLanguage(judgeDto.getLanguage())
.setPid(judgeDto.getPid())
.setUid(judgeDto.getUid())
.setStatus(-10) // 开始进入判题队列
.setSubmitTime(new Date())
.setIp(IpUtils.getUserIpAddr(request)));
if (result !=1){
return CommonResult.errorResponse("数据提交失败",CommonResult.STATUS_ERROR);
}
return toJudgeService.submitProblemJudge(judge);
}
/**
* @MethodName getJudgeList
* @Params * @param null
* @Description 通用查询判题记录
* @Return CommonResult
* @Since 2020/10/29
*/
@RequestMapping(value = "/get-judge-list",method = RequestMethod.GET)
public CommonResult getJudgeList(@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "currentPage", required = false) Integer currentPage,
@RequestParam(value = "searchPid", required = false) Long searchPid,
@RequestParam(value = "searchSource", required = false) String searchSource,
@RequestParam(value = "searchLanguage", required = false) String searchLanguage,
@RequestParam(value = "searchStatus", required = false) Integer searchStatus,
@RequestParam(value = "searchUsername", required = false) String searchUsername,
@RequestParam(value = "searchCid", required = true) Long searchCid) {
// 页数每页题数若为空设置默认值
if (currentPage == null || currentPage < 1) currentPage = 1;
if (limit == null || limit < 1) limit = 30;
// 设置无传参的空值设定
if (searchPid == null) { // 表示无题号过滤查询
searchPid = 0L;
}
if (searchStatus == null) { // 表示无结果过滤查询
searchStatus = -100;
}
Page<JudgeVo> commonJudgeList = judgeService.getCommonJudgeList(limit, currentPage, searchPid, searchSource, searchLanguage,
searchStatus, searchUsername, searchCid);
if (commonJudgeList.getTotal() == 0) { // 未查询到一条数据
return CommonResult.errorResponse("暂无数据", CommonResult.STATUS_NOT_FOUND);
} else {
return CommonResult.successResponse(commonJudgeList, "获取成功");
}
}
/**
* @MethodName getJudgeCase
* @Params * @param null
* @Description 获得指定提交id的测试样例前提是不能为比赛期间的题目
* @Return
* @Since 2020/10/29
*/
@GetMapping("/get-judge-case")
public CommonResult getJudgeCase(@RequestParam(value = "submitId", required = true) Long submitId,
@RequestParam(value = "pid", required = true) Long pid) {
// 如果该题目是还属于比赛期间的题目则禁止查看测试样例
Problem problem = problemService.getById(pid);
if (problem.getAuth() ==3){ // 3为比赛期间的题目
return CommonResult.errorResponse("对不起,该题测试样例不能查看!", CommonResult.STATUS_ACCESS_DENIED);
}
QueryWrapper<JudgeCase> wrapper = new QueryWrapper<JudgeCase>().eq("submit_id", submitId).orderByAsc("case_id");
List<JudgeCase> judgeCaseList = judgeCaseMapper.selectList(wrapper);
if (judgeCaseList.size() == 0) { // 未查询到一条数据
return CommonResult.errorResponse("暂无数据", CommonResult.STATUS_NOT_FOUND);
} else {
return CommonResult.successResponse(judgeCaseList, "获取成功");
}
}
}

View File

@ -27,7 +27,7 @@ public class ProblemController {
/**
* @MethodName getProblemList
* @Params * @param null
* @Params * @param null
* @Description 获取题目列表分页
* @Return CommonResult
* @Since 2020/10/27
@ -58,17 +58,25 @@ public class ProblemController {
/**
* @MethodName getProblemInfo
* @Params * @param null
* @Params * @param null
* @Description 获取指定题目的详情信息
* @Return CommonResult
* @Since 2020/10/27
*/
@RequestMapping(value = "/get-problem-info", method = RequestMethod.GET)
public CommonResult getProblemInfo(@RequestParam(value = "pid", required = true) Long pid) {
QueryWrapper<Problem> wrapper = new QueryWrapper<Problem>().eq("id", pid).eq("auth", 1);
public CommonResult getProblemInfo(@RequestParam(value = "pid", required = true) Long pid,
@RequestParam(value = "cid", required = true) Long cid) {
boolean isContestingProblem = false;
if (cid != 0) {
isContestingProblem = true;
}
QueryWrapper<Problem> wrapper = new QueryWrapper<Problem>().eq("id", pid)
.eq(isContestingProblem,"auth", 3)
.eq(!isContestingProblem, "auth",1);
Problem problem = problemService.getOne(wrapper);
if (problem == null) {
return CommonResult.errorResponse("该题号对应的题目不存在", CommonResult.STATUS_NOT_FOUND);
return CommonResult.errorResponse("该题号对应的题目不存在或暂时不能访问", CommonResult.STATUS_NOT_FOUND);
}
return CommonResult.successResponse(problem, "获取成功");
}

View File

@ -1,5 +1,7 @@
package top.hcode.hoj.dao;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import top.hcode.hoj.pojo.entity.JudgeCase;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
@ -11,6 +13,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
* @author Himit_ZH
* @since 2020-10-23
*/
@Mapper
@Repository
public interface JudgeCaseMapper extends BaseMapper<JudgeCase> {
}

View File

@ -0,0 +1,27 @@
package top.hcode.hoj.dao;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import top.hcode.hoj.pojo.entity.Judge;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import top.hcode.hoj.pojo.vo.JudgeVo;
import java.util.List;
/**
* <p>
* Mapper 接口
* </p>
*
* @author Himit_ZH
* @since 2020-10-23
*/
@Mapper
@Repository
public interface JudgeMapper extends BaseMapper<Judge> {
List<JudgeVo> getCommonJudgeList(IPage page, @Param("pid") long pid, @Param("source") String source,
@Param("language") String language, @Param("status") int status,
@Param("username") String username, @Param("cid") long cid);
}

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="top.hcode.hoj.dao.JudgeMapper">
<select id="getCommonJudgeList" resultType="top.hcode.hoj.pojo.vo.JudgeVo" useCache="false">
select j.uid,j.submit_id,j.submit_time,j.uid,u.username,u.nickname,j.pid,j.status,j.auth,
j.error_message,j.time,j.memory,j.length,j.language,j.cid,j.cpid,p.source,j.ip,j.judger
from problem p,user_info u,judge j
<where>
p.id = j.pid and j.uid = u.uuid
<if test="cid!=0 and cid!=null">
AND j.cid = #{cid}
</if>
<if test="pid!=0">
AND j.pid = #{pid}
</if>
<if test="username!='' and username!=null">
AND u.username = #{username}
</if>
<if test="source!=''and source!=null">
AND p.source = #{source}
</if>
<if test="language!=''and language!=null">
AND j.language = #{language}
</if>
<if test="status!=-100">
AND j.status = #{status}
</if>
</where>
order by j.submit_time,j.submit_id Desc
</select>
</mapper>

View File

@ -0,0 +1,39 @@
package top.hcode.hoj.pojo.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import org.springframework.lang.Nullable;
import javax.validation.constraints.NotBlank;
/**
* @Author: Himit_ZH
* @Date: 2020/10/30 11:03
* @Description: 用户代码提交类
*/
@Data
@Accessors(chain = true)
public class ToJudgeDto {
@NotBlank(message = "题目id不能为空")
private Long pid;
@NotBlank(message = "用户id不能为空")
private String uid;
@NotBlank(message = "代码语言选择不能为空")
private String language;
@NotBlank(message = "提交的代码不能为空")
private String code;
@NotBlank(message = "查看代码权限不能为空")
private Integer auth;
@NotBlank(message = "提交的比赛id所属不能为空若并非比赛提交请设置为0")
private Long cid;
@NotBlank(message = "提交的比赛题目id所属不能为空若并非比赛提交请设置为0")
private Long cpid;
}

View File

@ -0,0 +1,74 @@
package top.hcode.hoj.pojo.vo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
/**
* @Author: Himit_ZH
* @Date: 2020/10/29 13:08
* @Description:
*/
@Data
@ApiModel(value="返回的判题信息", description="")
public class JudgeVo {
@ApiModelProperty(value = "用户id")
private String uid;
@ApiModelProperty(value = "提交id")
@TableId(value = "submit_id", type = IdType.AUTO)
private Long submitId;
@ApiModelProperty(value = "用户名")
private String username;
@ApiModelProperty(value = "用户昵称")
private String nickname;
@ApiModelProperty(value = "题目id")
private Long pid;
@ApiModelProperty(value = "结果码具体参考文档")
private Date submitTime;
@ApiModelProperty(value = "结果码具体参考文档")
private Integer status;
@ApiModelProperty(value = "0为代码全部人可见1为仅自己可见。")
private Integer auth;
@ApiModelProperty(value = "错误提醒编译错误或者vj提醒")
private String errorMessage;
@ApiModelProperty(value = "运行时间")
private Integer time;
@ApiModelProperty(value = "运行内存")
private Integer memory;
@ApiModelProperty(value = "代码长度")
private Integer length;
@ApiModelProperty(value = "代码语言")
private String language;
@ApiModelProperty(value = "比赛id非比赛题目默认为0")
private Long cid;
@ApiModelProperty(value = "比赛中题目排序id非比赛题目默认为0")
private Long cpid;
@ApiModelProperty(value = "题目来源")
private String source;
@ApiModelProperty(value = "判题机ip")
private String judger;
@ApiModelProperty(value = "提交者所在ip")
private String ip;
}

View File

@ -0,0 +1,27 @@
package top.hcode.hoj.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import top.hcode.hoj.pojo.entity.Judge;
import com.baomidou.mybatisplus.extension.service.IService;
import top.hcode.hoj.pojo.vo.JudgeVo;
/**
* <p>
* 服务类
* </p>
*
* @author Himit_ZH
* @since 2020-10-23
*/
public interface JudgeService extends IService<Judge> {
Page<JudgeVo> getCommonJudgeList(int limit, int currentPage, long pid, String source,
String language, int status,
String username, long cid);
}

View File

@ -0,0 +1,20 @@
package top.hcode.hoj.service;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import top.hcode.hoj.common.exception.CloudHandler;
import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.pojo.dto.ToJudgeDto;
import top.hcode.hoj.pojo.entity.Judge;
@FeignClient(value = "hoj-judge-server",fallback = CloudHandler.class) //需要的判题微服务名
@Component
public interface ToJudgeService {
@PostMapping(value = "/judge")
public CommonResult submitProblemJudge(@RequestBody Judge judge);
}

Some files were not shown because too many files have changed in this diff Show More