use of top.hcode.hoj.pojo.entity.contest.Contest in project HOJ by HimitZH.
the class JudgeController method checkContestJudgeResult.
/**
* @MethodName checkContestJudgeResult
* @Params * @param submitIdListDto
* @Description 需要检查是否为封榜,是否可以查询结果,避免有人恶意查询
* @Return
* @Since 2021/6/11
*/
@RequestMapping(value = "/check-contest-submissions-status", method = RequestMethod.POST)
@RequiresAuthentication
public CommonResult checkContestJudgeResult(@RequestBody SubmitIdListDto submitIdListDto, HttpServletRequest request) {
if (submitIdListDto.getCid() == null) {
return CommonResult.errorResponse("查询比赛ID不能为空");
}
if (CollectionUtils.isEmpty(submitIdListDto.getSubmitIds())) {
return CommonResult.successResponse(new HashMap<>(), "查询的提交id列表为空!");
}
HttpSession session = request.getSession();
UserRolesVo userRolesVo = (UserRolesVo) session.getAttribute("userInfo");
// 是否为超级管理员
boolean isRoot = SecurityUtils.getSubject().hasRole("root");
Contest contest = contestService.getById(submitIdListDto.getCid());
boolean isContestAdmin = isRoot || userRolesVo.getUid().equals(contest.getUid());
// 如果是封榜时间且不是比赛管理员和超级管理员
boolean isSealRank = contestService.isSealRank(userRolesVo.getUid(), contest, true, isRoot);
QueryWrapper<Judge> queryWrapper = new QueryWrapper<>();
// lambada表达式过滤掉code
queryWrapper.select(Judge.class, info -> !info.getColumn().equals("code")).in("submit_id", submitIdListDto.getSubmitIds()).eq("cid", submitIdListDto.getCid()).between(isSealRank, "submit_time", contest.getStartTime(), contest.getSealRankTime());
List<Judge> judgeList = judgeService.list(queryWrapper);
HashMap<Long, Object> result = new HashMap<>();
for (Judge judge : judgeList) {
judge.setCode(null);
judge.setDisplayPid(null);
judge.setErrorMessage(null);
judge.setVjudgeUsername(null);
judge.setVjudgeSubmitId(null);
judge.setVjudgePassword(null);
if (!judge.getUid().equals(userRolesVo.getUid()) && !isContestAdmin) {
judge.setTime(null);
judge.setMemory(null);
judge.setLength(null);
}
result.put(judge.getSubmitId(), judge);
}
return CommonResult.successResponse(result, "获取最新判题数据成功!");
}
use of top.hcode.hoj.pojo.entity.contest.Contest in project HOJ by HimitZH.
the class JudgeController method getALLCaseResult.
/**
* @MethodName getJudgeCase
* @Params * @param null
* @Description 获得指定提交id的测试样例结果,暂不支持查看测试数据,只可看测试点结果,时间,空间,或者IO得分
* @Return
* @Since 2020/10/29
*/
@GetMapping("/get-all-case-result")
public CommonResult getALLCaseResult(@RequestParam(value = "submitId", required = true) Long submitId, HttpServletRequest request) {
Judge judge = judgeService.getById(submitId);
if (judge == null) {
return CommonResult.errorResponse("此提交数据不存在!");
}
Problem problem = problemService.getById(judge.getPid());
// 如果该题不支持开放测试点结果查看
if (!problem.getOpenCaseResult()) {
return CommonResult.successResponse(null, "对不起,该题测试样例详情不支持开放!");
}
HttpSession session = request.getSession();
UserRolesVo userRolesVo = (UserRolesVo) session.getAttribute("userInfo");
// 是否为超级管理员
boolean isRoot = SecurityUtils.getSubject().hasRole("root");
if (judge.getCid() != 0 && userRolesVo != null && !isRoot) {
Contest contest = contestService.getById(judge.getCid());
// 如果不是比赛管理员 比赛封榜不能看
if (!contest.getUid().equals(userRolesVo.getUid())) {
// 当前是比赛期间 同时处于封榜时间
if (contest.getSealRank() && contest.getStatus().intValue() == Constants.Contest.STATUS_RUNNING.getCode() && contest.getSealRankTime().before(new Date())) {
return CommonResult.successResponse(null, "对不起,该题测试样例详情不能查看!");
}
// 若是比赛题目,只支持OI查看测试点情况,ACM强制禁止查看,比赛管理员除外
if (problem.getType().intValue() == Constants.Contest.TYPE_ACM.getCode()) {
return CommonResult.successResponse(null, "对不起,该题测试样例详情不能查看!");
}
}
}
QueryWrapper<JudgeCase> wrapper = new QueryWrapper<>();
if (userRolesVo == null || (!isRoot && !SecurityUtils.getSubject().hasRole("admin") && !SecurityUtils.getSubject().hasRole("problem_admin"))) {
wrapper.select("time", "memory", "score", "status", "user_output");
}
wrapper.eq("submit_id", submitId).last("order by length(input_data) asc,input_data asc");
// 当前所有测试点只支持 空间 时间 状态码 IO得分 输出文件名 输入文件名和错误信息提示查看而已
List<JudgeCase> judgeCaseList = judgeCaseService.list(wrapper);
if (judgeCaseList.isEmpty()) {
// 未查询到一条数据
return CommonResult.successResponse(null, "暂无数据");
} else {
return CommonResult.successResponse(judgeCaseList, "获取成功");
}
}
use of top.hcode.hoj.pojo.entity.contest.Contest in project HOJ by HimitZH.
the class ContestAdminController method getContestACInfo.
/**
* @MethodName getContestACInfo
* @Params * @param null
* @Description 获取各个用户的ac情况,仅限于比赛管理者可查看
* @Return
* @Since 2021/1/17
*/
@GetMapping("/get-contest-ac-info")
@RequiresAuthentication
public CommonResult getContestACInfo(@RequestParam("cid") Long cid, @RequestParam(value = "currentPage", required = false) Integer currentPage, @RequestParam(value = "limit", required = false) Integer limit, HttpServletRequest request) {
HttpSession session = request.getSession();
UserRolesVo userRolesVo = (UserRolesVo) session.getAttribute("userInfo");
// 获取本场比赛的状态
Contest contest = contestService.getById(cid);
// 超级管理员或者该比赛的创建者,则为比赛管理者
boolean isRoot = SecurityUtils.getSubject().hasRole("root");
if (!isRoot && !contest.getUid().equals(userRolesVo.getUid())) {
return CommonResult.errorResponse("对不起,你无权查看!", CommonResult.STATUS_FORBIDDEN);
}
if (currentPage == null || currentPage < 1)
currentPage = 1;
if (limit == null || limit < 1)
limit = 30;
// 获取当前比赛的,状态为ac,未被校验的排在签名
IPage<ContestRecord> contestRecords = contestRecordService.getACInfo(currentPage, limit, Constants.Contest.RECORD_AC.getCode(), cid, contest.getUid());
return CommonResult.successResponse(contestRecords, "查询成功");
}
use of top.hcode.hoj.pojo.entity.contest.Contest in project HOJ by HimitZH.
the class ProblemController method getUserProblemStatus.
/**
* @MethodName getUserProblemStatus
* @Params * @param UidAndPidListDto
* @Description 获取用户对应该题目列表中各个题目的做题情况
* @Return CommonResult
* @Since 2020/12/29
*/
@RequiresAuthentication
@PostMapping("/get-user-problem-status")
public CommonResult getUserProblemStatus(@Validated @RequestBody PidListDto pidListDto, HttpServletRequest request) {
// 需要获取一下该token对应用户的数据
HttpSession session = request.getSession();
UserRolesVo userRolesVo = (UserRolesVo) session.getAttribute("userInfo");
HashMap<Long, Object> result = new HashMap<>();
// 先查询判断该用户对于这些题是否已经通过,若已通过,则无论后续再提交结果如何,该题都标记为通过
QueryWrapper<Judge> queryWrapper = new QueryWrapper<>();
queryWrapper.select("distinct pid,status,submit_time,score").in("pid", pidListDto.getPidList()).eq("uid", userRolesVo.getUid()).orderByDesc("submit_time");
if (pidListDto.getIsContestProblemList()) {
// 如果是比赛的提交记录需要判断cid
queryWrapper.eq("cid", pidListDto.getCid());
} else {
queryWrapper.eq("cid", 0);
}
List<Judge> judges = judgeService.list(queryWrapper);
boolean isACMContest = true;
Contest contest = null;
if (pidListDto.getIsContestProblemList()) {
contest = contestService.getById(pidListDto.getCid());
if (contest == null) {
return CommonResult.errorResponse("比赛参数错误!");
}
isACMContest = contest.getType().intValue() == Constants.Contest.TYPE_ACM.getCode();
}
for (Judge judge : judges) {
// 如果是比赛的题目列表状态
HashMap<String, Object> temp = new HashMap<>();
if (pidListDto.getIsContestProblemList()) {
if (!isACMContest) {
if (!result.containsKey(judge.getPid())) {
// 只有比赛结束可以看到,比赛管理员与超级管理员的提交除外
if (contestService.isSealRank(userRolesVo.getUid(), contest, true, SecurityUtils.getSubject().hasRole("root"))) {
temp.put("status", Constants.Judge.STATUS_SUBMITTED_UNKNOWN_RESULT.getStatus());
temp.put("score", null);
} else {
temp.put("status", judge.getStatus());
temp.put("score", judge.getScore());
}
result.put(judge.getPid(), temp);
}
} else {
// 如果该题目已通过,且同时是为不封榜前提交的,则强制写为通过(0)
if (judge.getStatus().intValue() == Constants.Judge.STATUS_ACCEPTED.getStatus()) {
temp.put("status", Constants.Judge.STATUS_ACCEPTED.getStatus());
temp.put("score", null);
result.put(judge.getPid(), temp);
} else if (!result.containsKey(judge.getPid())) {
// 还未写入,则使用最新一次提交的结果
temp.put("status", judge.getStatus());
temp.put("score", null);
result.put(judge.getPid(), temp);
}
}
} else {
// 不是比赛题目
if (judge.getStatus().intValue() == Constants.Judge.STATUS_ACCEPTED.getStatus()) {
// 如果该题目已通过,则强制写为通过(0)
temp.put("status", Constants.Judge.STATUS_ACCEPTED.getStatus());
result.put(judge.getPid(), temp);
} else if (!result.containsKey(judge.getPid())) {
// 还未写入,则使用最新一次提交的结果
temp.put("status", judge.getStatus());
result.put(judge.getPid(), temp);
}
}
}
// 再次检查,应该可能从未提交过该题,则状态写为-10
for (Long pid : pidListDto.getPidList()) {
// 如果是比赛的题目列表状态
if (pidListDto.getIsContestProblemList()) {
if (!result.containsKey(pid)) {
HashMap<String, Object> temp = new HashMap<>();
temp.put("score", null);
temp.put("status", Constants.Judge.STATUS_NOT_SUBMITTED.getStatus());
result.put(pid, temp);
}
} else {
if (!result.containsKey(pid)) {
HashMap<String, Object> temp = new HashMap<>();
temp.put("status", Constants.Judge.STATUS_NOT_SUBMITTED.getStatus());
result.put(pid, temp);
}
}
}
return CommonResult.successResponse(result, "查询成功");
}
use of top.hcode.hoj.pojo.entity.contest.Contest in project HOJ by HimitZH.
the class ContestRecordServiceImpl method submitContestProblem.
@Override
@Transactional(rollbackFor = Exception.class)
public CommonResult submitContestProblem(ToJudgeDto judgeDto, UserRolesVo userRolesVo, Judge judge) {
// 首先判断一下比赛的状态是否是正在进行,结束状态都不能提交,比赛前比赛管理员可以提交
Contest contest = contestService.getById(judgeDto.getCid());
if (contest == null) {
return CommonResult.errorResponse("对不起,该比赛不存在!");
}
if (contest.getStatus().intValue() == Constants.Contest.STATUS_ENDED.getCode()) {
return CommonResult.errorResponse("比赛已结束,不可再提交!");
}
// 是否为超级管理员或者该比赛的创建者,则为比赛管理者
boolean root = SecurityUtils.getSubject().hasRole("root");
if (!root && !contest.getUid().equals(userRolesVo.getUid())) {
if (contest.getStatus().intValue() == Constants.Contest.STATUS_SCHEDULED.getCode()) {
return CommonResult.errorResponse("比赛未开始,不可提交!");
}
// 需要检查是否有权限在当前比赛进行提交
CommonResult checkResult = contestService.checkJudgeAuth(contest, userRolesVo.getUid());
if (checkResult != null) {
return checkResult;
}
if (contest.getAuth().equals(Constants.Contest.AUTH_PROTECT.getCode()) && contest.getOpenAccountLimit() && !contestService.checkAccountRule(contest.getAccountLimitRule(), userRolesVo.getUsername())) {
return CommonResult.errorResponse("对不起!本次比赛只允许特定账号规则的用户参赛!", CommonResult.STATUS_ACCESS_DENIED);
}
}
// 查询获取对应的pid和cpid
QueryWrapper<ContestProblem> contestProblemQueryWrapper = new QueryWrapper<>();
contestProblemQueryWrapper.eq("cid", judgeDto.getCid()).eq("display_id", judgeDto.getPid());
ContestProblem contestProblem = contestProblemMapper.selectOne(contestProblemQueryWrapper);
judge.setCpid(contestProblem.getId()).setPid(contestProblem.getPid());
Problem problem = problemService.getById(contestProblem.getPid());
if (problem.getAuth() == 2) {
return CommonResult.errorResponse("错误!当前题目不可提交!", CommonResult.STATUS_FORBIDDEN);
}
judge.setDisplayPid(problem.getProblemId());
// 将新提交数据插入数据库
judgeMapper.insert(judge);
// 同时初始化写入contest_record表
ContestRecord contestRecord = new ContestRecord();
contestRecord.setDisplayId(judgeDto.getPid()).setCpid(contestProblem.getId()).setSubmitId(judge.getSubmitId()).setPid(judge.getPid()).setUsername(userRolesVo.getUsername()).setRealname(userRolesVo.getRealname()).setUid(userRolesVo.getUid()).setCid(judge.getCid()).setSubmitTime(judge.getSubmitTime());
if (contest.getStatus().intValue() == Constants.Contest.STATUS_SCHEDULED.getCode()) {
contestRecord.setTime(0L);
} else {
// 设置比赛开始时间到提交时间之间的秒数
contestRecord.setTime(DateUtil.between(contest.getStartTime(), judge.getSubmitTime(), DateUnit.SECOND));
}
contestRecordMapper.insert(contestRecord);
return null;
}
Aggregations