项目重构,添加评测,判题服务模块
This commit is contained in:
parent
09c4f131cc
commit
d86c1e11bd
216
README.md
216
README.md
|
@ -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,33 +213,37 @@ 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提醒) |
|
||||
| error_message | String | | 错误提醒(编译错误,或者vj提醒) |
|
||||
| time | int | | 运行时间 |
|
||||
| memory | int | | 所耗内存 |
|
||||
| length | int | | 代码长度 |
|
||||
|
@ -231,6 +253,7 @@ judge表
|
|||
| judger | String | | 判题机ip |
|
||||
| ip | String | | 提交者ip |
|
||||
| cid | int | | 题目来源的比赛id,默认为0 |
|
||||
| version | int | | 乐观锁 |
|
||||
| gmt_create | datetime | | 创建时间 |
|
||||
| gmt_modified | datetime | | 修改时间 |
|
||||
|
||||
|
@ -290,12 +313,11 @@ 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 | | 修改时间 |
|
||||
|
||||
|
@ -408,7 +430,7 @@ comment_tag表 讨论标签表
|
|||
|
||||
|
||||
|
||||
# 四、后端数据接口
|
||||
# 四、后端交互系统
|
||||
|
||||
|
||||
|
||||
|
@ -894,3 +916,159 @@ data数据
|
|||
| ac | int | 总通过数 |
|
||||
| Rating | int | cf得分 |
|
||||
| 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 | 消息 |
|
||||
|
||||
|
||||
|
||||
###(二)、判题机模块
|
|
@ -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>
|
|
@ -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>
|
|
@ -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) {
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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 {
|
||||
}
|
|
@ -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) {
|
|
@ -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, "获取成功");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -64,11 +64,19 @@ public class ProblemController {
|
|||
* @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, "获取成功");
|
||||
}
|
|
@ -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> {
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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>
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
|
@ -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
Loading…
Reference in New Issue