package com.example.onlinejudge.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.example.onlinejudge.constant.CommonConstant; import com.example.onlinejudge.exception.BusinessException; import com.example.onlinejudge.judge.JudgeService; import com.example.onlinejudge.mapper.QuestionSubmitMapper; import com.example.onlinejudge.model.VO.QuestionSubmitVO; import com.example.onlinejudge.model.dto.questionSubmit.QuestionSubmitAddRequest; import com.example.onlinejudge.model.dto.questionSubmit.QuestionSubmitQueryRequest; import com.example.onlinejudge.model.entity.Question; import com.example.onlinejudge.model.entity.QuestionSubmit; import com.example.onlinejudge.model.entity.User; import com.example.onlinejudge.model.entity.result.ResultCode; import com.example.onlinejudge.model.enums.QuestionSubmitLanguageEnum; import com.example.onlinejudge.model.enums.QuestionSubmitStatusEnum; import com.example.onlinejudge.service.QuestionService; import com.example.onlinejudge.service.QuestionSubmitService; import com.example.onlinejudge.service.UserService; import com.example.onlinejudge.utils.SqlUtils; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; @Service public class QuestionSubmitServiceImpl extends ServiceImpl implements QuestionSubmitService { @Resource private QuestionService questionService; @Resource private UserService userService; @Resource @Lazy private JudgeService judgeService; /** * 提交题目 * * @param questionSubmitAddRequest * @param loginUser * @return */ @Override public long doQuestionSubmit(QuestionSubmitAddRequest questionSubmitAddRequest, Long loginUserId) { // 校验编程语言是否合法 String language = questionSubmitAddRequest.getLanguage(); QuestionSubmitLanguageEnum languageEnum = QuestionSubmitLanguageEnum.getEnumByValue(language); if (languageEnum == null) { throw new BusinessException(ResultCode.PARAM_IS_INVALID, "编程语言错误"); } long questionId = questionSubmitAddRequest.getQuestionId(); // 判断实体是否存在,根据类别获取实体 Question question = questionService.getById(questionId); if (question == null) { throw new BusinessException(ResultCode.NOT_FOUND_ERROR); } // 是否已提交题目 // 每个用户串行提交题目 QuestionSubmit questionSubmit = new QuestionSubmit(); questionSubmit.setUserId(loginUserId); questionSubmit.setQuestionId(questionId); questionSubmit.setCode(questionSubmitAddRequest.getCode()); questionSubmit.setLanguage(language); // 设置初始状态 questionSubmit.setStatus(QuestionSubmitStatusEnum.WAITING.getValue()); questionSubmit.setJudgeInfo("{}"); boolean save = this.save(questionSubmit); if (!save){ throw new BusinessException(ResultCode.SYSTEM_ERROR, "数据插入失败"); } Long questionSubmitId = questionSubmit.getId(); // 执行判题服务 CompletableFuture.runAsync(() -> { judgeService.doJudge(questionSubmitId); }); return questionSubmitId; } /** * 获取查询包装类(用户根据哪些字段查询,根据前端传来的请求对象,得到 mybatis 框架支持的查询 QueryWrapper 类) * * @param questionSubmitQueryRequest * @return */ @Override public QueryWrapper getQueryWrapper(QuestionSubmitQueryRequest questionSubmitQueryRequest) { QueryWrapper queryWrapper = new QueryWrapper<>(); if (questionSubmitQueryRequest == null) { return queryWrapper; } String language = questionSubmitQueryRequest.getLanguage(); Integer status = questionSubmitQueryRequest.getStatus(); Long questionId = questionSubmitQueryRequest.getQuestionId(); Long userId = questionSubmitQueryRequest.getUserId(); String sortField = questionSubmitQueryRequest.getSortField(); String sortOrder = questionSubmitQueryRequest.getSortOrder(); // 拼接查询条件 queryWrapper.eq(StringUtils.isNotBlank(language), "language", language); queryWrapper.eq(ObjectUtils.isNotEmpty(userId), "userId", userId); queryWrapper.eq(ObjectUtils.isNotEmpty(questionId), "questionId", questionId); queryWrapper.eq(QuestionSubmitStatusEnum.getEnumByValue(status) != null, "status", status); queryWrapper.eq("isDelete", false); queryWrapper.orderBy(SqlUtils.validSortField(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC), sortField); return queryWrapper; } @Override public QuestionSubmitVO getQuestionSubmitVO(QuestionSubmit questionSubmit, User loginUser) { QuestionSubmitVO questionSubmitVO = QuestionSubmitVO.objToVo(questionSubmit); // 脱敏:仅本人和管理员能看见自己(提交 userId 和登录用户 id 不同)提交的代码 long userId = loginUser.getId(); // 处理脱敏 //TODO && !userService.isAdmin(loginUser) if (userId != questionSubmit.getUserId() ) { questionSubmitVO.setCode(null); } return questionSubmitVO; } @Override public Page getQuestionSubmitVOPage(Page questionSubmitPage, User loginUser) { List questionSubmitList = questionSubmitPage.getRecords(); Page questionSubmitVOPage = new Page<>(questionSubmitPage.getCurrent(), questionSubmitPage.getSize(), questionSubmitPage.getTotal()); if (CollectionUtils.isEmpty(questionSubmitList)) { return questionSubmitVOPage; } List questionSubmitVOList = questionSubmitList.stream() .map(questionSubmit -> getQuestionSubmitVO(questionSubmit, loginUser)) .collect(Collectors.toList()); questionSubmitVOPage.setRecords(questionSubmitVOList); return questionSubmitVOPage; } }