☰
【项目】【在线判题系统】c端:用户答题获取题目
2026/10/17 2:08:16 网站建设 项目流程

目录

  • 一、答题获取上下题
    • 1.1 controller
    • 1.2 service
    • 1.3 缓存方法
    • 1.4 redis
    • 1.5 b端增删题目修改
  • 二、竞赛题目列表获取
  • 2.1 controller
    • 2.2 service
    • 2.3 缓存调用
    • 2.4 b端撤销发布
  • 三、用户竞赛答题获取上下题
    • 3.1 controller
    • 3.2 service
    • 3.3 缓存

一、答题获取上下题

1.1 controller

oj-modules/oj-friend/src/main/java/com/yj/friend/controller/question/QuestionController.java

@GetMapping("/preQuestion")publicR<String>preQuestion(LongquestionId){returnR.success(questionService.preQuestion(questionId));}@GetMapping("/nextQuestion")publicR<String>nextQuestion(LongquestionId){returnR.success(questionService.nextQuestion(questionId));}

1.2 service

oj-modules/oj-friend/src/main/java/com/yj/friend/service/question/IQuestionService.java,接口定义

StringpreQuestion(LongquestionId);StringnextQuestion(LongquestionId);

oj-modules/oj-friend/src/main/java/com/yj/friend/service/question/impl/QuestionServiceImpl.java,方法,先从缓存获取,没有再从数据库获取

@OverridepublicStringpreQuestion(LongquestionId){refreshQuestionList();Longl=questionCacheManage.preQuestion(questionId);returnl.toString();}@OverridepublicStringnextQuestion(LongquestionId){refreshQuestionList();Longl=questionCacheManage.nextQuestion(questionId);returnl.toString();}

1.3 缓存方法

oj-modules/oj-friend/src/main/java/com/yj/friend/manage/QuestionCacheManage.java,题目相关的缓存方法,获得缓存的数量,以及上下题的id

packagecom.yj.friend.manage;importcn.hutool.core.collection.CollectionUtil;importcom.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;importcom.yj.common.core.constants.CacheConstants;importcom.yj.common.core.enums.ResultCodeEnum;importcom.yj.common.redis.service.RedisService;importcom.yj.common.security.exception.ServiceException;importcom.yj.friend.domain.question.QuestionDO;importcom.yj.friend.mapper.question.QuestionMapper;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Component;importjava.util.List;@ComponentpublicclassQuestionCacheManage{@AutowiredprivateRedisServiceredisService;@AutowiredprivateQuestionMapperquestionMapper;//获取缓存中的数据数量publicLonggetListSize(){returnredisService.getListSize(CacheConstants.QUESTION_LIST);}//刷新缓存publicvoidrefreshCache(){List<QuestionDO>questionDOList=questionMapper.selectList(newLambdaQueryWrapper<QuestionDO>().orderByAsc(QuestionDO::getCreateTime).select(QuestionDO::getQuestionId));if(CollectionUtil.isEmpty(questionDOList))return;List<Long>list=questionDOList.stream().map(QuestionDO::getQuestionId).toList();redisService.rightPushAll(CacheConstants.QUESTION_LIST,list);}publicLongpreQuestion(LongquestionId){Longindex=redisService.indexOfList(CacheConstants.QUESTION_LIST,questionId);//第一题if(0==index){thrownewServiceException(ResultCodeEnum.FAILED_FIRST_QUESTION);}//获取上一题returnredisService.indexList(CacheConstants.QUESTION_LIST,index-1,Long.class);}publicLongnextQuestion(LongquestionId){Longindex=redisService.indexOfList(CacheConstants.QUESTION_LIST,questionId);LonglistSize=getListSize();//最后一题if(listSize-1==index){thrownewServiceException(ResultCodeEnum.FAILED_LAST_QUESTION);}//获取下一题returnredisService.indexList(CacheConstants.QUESTION_LIST,index+1,Long.class);}}

1.4 redis

oj-common/oj-common-redis/src/main/java/com/yj/common/redis/service/RedisService.java,新增获取索引与数据的方法。

/** * 底层使用list结构,获取指定数据的索引 */public<T>LongindexOfList(finalStringkey,Tvalue){returnredisTemplate.opsForList().indexOf(key,value);}/** * 底层使用list结构,获取指定索引的数据 */public<T>TindexList(finalStringkey,Longindex,Class<T>clazz){Objectindex1=redisTemplate.opsForList().index(key,index);returnJSON.parseObject(String.valueOf(index1),clazz);}

1.5 b端增删题目修改

oj-modules/oj-system/src/main/java/com/yj/system/manage/QuestionCacheManage.java缓存使用方法:

packagecom.yj.system.manage;importcom.yj.common.core.constants.CacheConstants;importcom.yj.common.redis.service.RedisService;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Component;importjava.util.List;@ComponentpublicclassQuestionCacheManage{@AutowiredprivateRedisServiceredisService;publicvoidaddCache(LongquestionId){redisService.leftPushForList(CacheConstants.QUESTION_LIST,questionId);}publicvoiddeleteCache(LongquestionId){redisService.removeForList(CacheConstants.QUESTION_LIST,questionId);}}

service修改:增加缓存的增删

@Overridepublicintdelete(LongquestionId){// 1. 判断题目是否存在QuestionDOquestionDO=questionMapper.selectById(questionId);if(null==questionDO){thrownewServiceException(ResultCodeEnum.FAILED_NOT_EXISTS);}// 2. 删除esquestionRepository.deleteById(questionId);// 3. 删除缓存questionCacheManage.deleteCache(questionId);// 4. 删除数据库returnquestionMapper.deleteById(questionId);}@Overridepublicbooleanadd(QuestionAddDTOquestionAddDTO){// 1.构建查询条件:标题 或 内容 重复List<QuestionDO>questionDOS=questionMapper.selectList(Wrappers.lambdaQuery(QuestionDO.class).and(wrapper->wrapper.eq(QuestionDO::getTitle,questionAddDTO.getTitle()).or().eq(QuestionDO::getContent,questionAddDTO.getContent())));// 2. 如果存在重复数据,抛出异常if(CollectionUtil.isNotEmpty(questionDOS)){thrownewServiceException(ResultCodeEnum.FAILED_ALREADY_EXISTS);}// 3. 拷贝属性并插入QuestionDOquestionDO=newQuestionDO();BeanUtil.copyProperties(questionAddDTO,questionDO);// 4. 插入数据库introw=questionMapper.insert(questionDO);if(row<=0){returnfalse;}// 5. 插入esQuestionESquestionES=BeanUtil.copyProperties(questionDO,QuestionES.class);questionRepository.save(questionES);// 6. 缓存questionCacheManage.addCache(questionDO.getQuestionId());returntrue;}

二、竞赛题目列表获取

2.1 controller

oj-modules/oj-friend/src/main/java/com/yj/friend/controller/exam/ExamController.java

@GetMapping("/getFirstQuestion")publicR<String>getFirstQuestion(LongexamId){returnR.success(examService.getFirstQuestion(examId));}

2.2 service

oj-modules/oj-friend/src/main/java/com/yj/friend/service/exam/IExamService.java,方法接口

StringgetFirstQuestion(LongexamId);

oj-modules/oj-friend/src/main/java/com/yj/friend/service/exam/impl/ExamServiceImpl.java,方法实现

@OverridepublicStringgetFirstQuestion(LongexamId){LongquestionListSize=examCacheManager.getExamQuestionListSize(examId);if(questionListSize==null||questionListSize<=0){//如果缓存中没有数据,刷新缓存examCacheManager.refreshExamQuestionCache(examId);}//从缓存中获取第一个题目returnexamCacheManager.getFirstQuestion(examId).toString();}

2.3 缓存调用

oj-modules/oj-friend/src/main/java/com/yj/friend/service/exam/impl/ExamServiceImpl.java

//刷新竞赛题目缓存publicvoidrefreshExamQuestionCache(LongexamId){//查询竞赛题目List<ExamQuestionDO>examQuestionDOS=examQuestionMapper.selectList(newLambdaQueryWrapper<ExamQuestionDO>().eq(ExamQuestionDO::getExamId,examId).orderByAsc(ExamQuestionDO::getQuestionOrder).select(ExamQuestionDO::getQuestionId));//判断是否有数据if(CollectionUtil.isEmpty(examQuestionDOS))return;//将题目题目id转换为listList<Long>questionIdList=examQuestionDOS.stream().map(ExamQuestionDO::getQuestionId).toList();//刷新缓存StringexamQuestionListKey=getExamQuestionListKey(examId);redisService.rightPushAll(examQuestionListKey,questionIdList);Longseconds=ChronoUnit.SECONDS.between(LocalDateTime.now(),LocalDateTime.now().plusSeconds(1).withHour(0).withMinute(0).withSecond(0).withNano(0));redisService.expire(examQuestionListKey,seconds,TimeUnit.SECONDS);}//从缓存中获取第一个题目publicLonggetFirstQuestion(LongexamId){returnredisService.indexList(getExamQuestionListKey(examId),0L,Long.class);}privateStringgetExamQuestionListKey(LongexamId){returnCacheConstants.EXAM_QUESTION_LIST+examId;}

2.4 b端撤销发布

oj-modules/oj-system/src/main/java/com/yj/system/manage/ExamCacheManage.java

publicvoiddeleteCache(LongexamId){redisService.removeForList(getExamListKey(),examId);redisService.deleteObject(getDetailKey(examId));redisService.deleteObject(getExamQuestionListKey(examId));}privateStringgetExamQuestionListKey(LongexamId){returnCacheConstants.EXAM_QUESTION_LIST+examId;}

三、用户竞赛答题获取上下题

3.1 controller

oj-modules/oj-friend/src/main/java/com/yj/friend/controller/exam/ExamController.java

@GetMapping("/preQuestion")publicR<String>preQuestion(LongexamId,LongquestionId){returnR.success(examService.preQuestion(examId,questionId));}@GetMapping("/nextQuestion")publicR<String>nextQuestion(LongexamId,LongquestionId){returnR.success(examService.nextQuestion(examId,questionId));}

3.2 service

oj-modules/oj-friend/src/main/java/com/yj/friend/service/exam/IExamService.java,接口方法

StringpreQuestion(LongexamId,LongquestionId);StringnextQuestion(LongexamId,LongquestionId);

oj-modules/oj-friend/src/main/java/com/yj/friend/service/exam/impl/ExamServiceImpl.java

//从竞赛缓存题目列表中获取上一个题目@OverridepublicStringpreQuestion(LongexamId,LongquestionId){refreshQuestionList(examId);Longl=examCacheManager.preQuestion(examId,questionId);returnl.toString();}//从竞赛缓存题目列表中获取下一个题目@OverridepublicStringnextQuestion(LongexamId,LongquestionId){refreshQuestionList(examId);Longl=examCacheManager.nextQuestion(examId,questionId);returnl.toString();}

3.3 缓存

oj-modules/oj-friend/src/main/java/com/yj/friend/manage/ExamCacheManager.java

//从竞赛缓存题目列表中获取上一个题目publicLongpreQuestion(LongexamId,LongquestionId){//获取题目在列表中的索引StringexamQuestionListKey=getExamQuestionListKey(examId);Longindex=redisService.indexOfList(examQuestionListKey,questionId);if(0==index){thrownewServiceException(ResultCodeEnum.FAILED_FIRST_QUESTION);}returnredisService.indexList(examQuestionListKey,index-1,Long.class);}//从竞赛缓存题目列表中获取下一个题目publicLongnextQuestion(LongexamId,LongquestionId){//获取题目在列表中的索引StringexamQuestionListKey=getExamQuestionListKey(examId);Longindex=redisService.indexOfList(examQuestionListKey,questionId);longsize=getExamQuestionListSize(examId)-1;if(size==index){thrownewServiceException(ResultCodeEnum.FAILED_LAST_QUESTION);}returnredisService.indexList(examQuestionListKey,index+1,Long.class);}

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询