ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

【项目】【在线判题系统】c端:我的竞赛列表

【项目】【在线判题系统】c端:我的竞赛列表

目录

  • 一、controller
  • 二、service
  • 三、mapper
  • 四、缓存修改
  • 五、前端

一、controller

这个跟前面的竞赛列表展示逻辑一样,只是需要加上userId的筛选条件即可。

oj-modules/oj-friend/src/main/java/com/yj/friend/controller/user/UserExamController.java

@GetMapping("/list")publicTableDataInforedisList(ExamQueryDTOexamQueryDTO){returnuserExamService.list(examQueryDTO);}

二、service

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

TableDataInfolist(ExamQueryDTOexamQueryDTO);

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

@OverridepublicTableDataInfolist(ExamQueryDTOexamQueryDTO){LonguserId=ThreadLocalUtil.get(Constants.USER_ID,Long.class);examQueryDTO.setType(examListTypeEnum.USER_EXAM_LIST.getValue());//从redis当中获取 竞赛列表的数据Longtotal=examCacheManager.getListSize(examQueryDTO.getType(),userId);List<ExamVO>examVOList;if(total==null||total<=0){//缓存没有PageHelper.startPage(examQueryDTO.getPageNum(),examQueryDTO.getPageSize());examVOList=userExamMapper.selectUserExamList(userId);examCacheManager.refreshCache(examQueryDTO.getType(),userId);total=newPageInfo<>(examVOList).getTotal();}else{//缓存有examVOList=examCacheManager.getExamVOList(examQueryDTO,userId);total=examCacheManager.getListSize(examQueryDTO.getType(),userId);}if(CollectionUtil.isEmpty(examVOList)){returnTableDataInfo.empty();}returnTableDataInfo.success(examVOList,total);}

三、mapper

oj-modules/oj-friend/src/main/java/com/yj/friend/mapper/user/UserExamMapper.java

List<ExamVO>selectUserExamList(LonguserId);

xml写自定义sql,联表查询

<?xml version="1.0"encoding="UTF-8"?><!DOCTYPEmapperPUBLIC"-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.yj.friend.mapper.user.UserExamMapper"><!--竞赛列表查询--><select id="selectUserExamList"resultType="com.yj.friend.domain.exam.vo.ExamVO">SELECTe.exam_id,e.title,e.start_time,e.end_timeFROMtb_user_exam ueJOINtb_exam eONue.exam_id=e.exam_idWHEREue.user_id=#{userId}ORDERBYue.create_timeDESC</select></mapper>

四、缓存修改

oj-modules/oj-friend/src/main/java/com/yj/friend/manage/ExamCacheManager.java刷新缓存方法添加我的竞赛。数据库查询逻辑和获取缓存头也添加,

//刷新缓存逻辑publicvoidrefreshCache(IntegerexamListType,LonguserId){List<ExamDO>examList=newArrayList<>();if(examListTypeEnum.EXAM_UN_FINISH_LIST.getValue().equals(examListType)){//查询未完赛的竞赛列表examList=examMapper.selectList(newLambdaQueryWrapper<ExamDO>().select(ExamDO::getExamId,ExamDO::getTitle,ExamDO::getStartTime,ExamDO::getEndTime).gt(ExamDO::getEndTime,LocalDateTime.now()).eq(ExamDO::getStatus,Constants.TRUE).orderByDesc(ExamDO::getCreateTime));}elseif(examListTypeEnum.EXAM_HISTORY_LIST.getValue().equals(examListType)){//查询历史竞赛examList=examMapper.selectList(newLambdaQueryWrapper<ExamDO>().select(ExamDO::getExamId,ExamDO::getTitle,ExamDO::getStartTime,ExamDO::getEndTime).le(ExamDO::getEndTime,LocalDateTime.now()).eq(ExamDO::getStatus,Constants.TRUE).orderByDesc(ExamDO::getCreateTime));}elseif(examListTypeEnum.USER_EXAM_LIST.getValue().equals(examListType)){//查询用户报名的竞赛列表List<ExamVO>examVOS=userExamMapper.selectUserExamList(userId);examList=BeanUtil.copyToList(examVOS,ExamDO.class);}if(CollectionUtil.isEmpty(examList)){return;}privateList<ExamVO>getExamListByDB(ExamQueryDTOexamQueryDTO,LonguserId){PageHelper.startPage(examQueryDTO.getPageNum(),examQueryDTO.getPageSize());if(examListTypeEnum.USER_EXAM_LIST.getValue().equals(examQueryDTO.getType())){//查询用户报名的竞赛列表returnuserExamMapper.selectUserExamList(userId);}else{//查询C端的竞赛列表returnexamMapper.selectExamList(examQueryDTO);}}privateStringgetExamListKey(IntegerexamListType,LonguserId){if(examListTypeEnum.EXAM_UN_FINISH_LIST.getValue().equals(examListType)){returnCacheConstants.EXAM_UNFINISHED_LIST;}elseif(examListTypeEnum.EXAM_HISTORY_LIST.getValue().equals(examListType)){returnCacheConstants.EXAM_HISTORY_LIST;}else{returnCacheConstants.USER_EXAM_LIST+userId;}}

五、前端

oj-vue\oj-fe-c\src\views\UserExam.vue

<template><divclass="my-exam-page"><divclass="exam-list-block"><divclass="exam-list-header"><spanclass="ex-title">我的竞赛</span><spanclass="exam-list-back"@click="goBack">返回</span></div><divclass="exam-list-content"v-for="(exam, index) in myExamList":key="index"><imgsrc="@/assets/ide/jingsai.png"class="image"/><divclass="exam-content"><divclass="title">{{ exam.title }}</div><divclass="date"><span>比赛时间:</span>{{ exam.startTime }} ~ {{ exam.endTime }}</div></div><div><divclass="exam-end-lable-list"v-if="isHistoryExam(exam)"><spanclass="exam-end-lable">已完赛</span><el-buttonclass="exam-rank-lable"type="text"@click="togglePopover(exam.examId)">查看排名</el-button><el-buttonclass="exam-rank-lable"type="text"@click="goHistoryExam(exam)">竞赛练习</el-button></div><divclass="exam-status-lable exam-end-lable-list"v-else-if="isNotStart(exam)">未开赛</div><divclass="exam-end-lable-list"v-else><el-buttonclass="exam-rank-lable"type="text"plain@click="goExam(exam)">开始答题</el-button></div></div></div><divclass="my-exam-pagination"><!-- 增加分页展示器 --><el-paginationbackgroundlayout="total, sizes, prev, pager, next, jumper":total="total"v-model:current-page="params.pageNum"v-model:page-size="params.pageSize":page-sizes="[5, 10, 15, 20]"@size-change="handleSizeChange"@current-change="handleCurrentChange"/></div></div></div></template><scriptsetup>import{reactive,ref}from'vue'import{getMyExamListService,}from"@/apis/exam"importrouterfrom'@/router'constmyExamList=ref([])//消息列表consttotal=ref(0)constparams=reactive({pageNum:1,pageSize:10,})// 分页functionhandleSizeChange(newSize){params.pageNum=1getMyExamList()}functionhandleCurrentChange(newPage){getMyExamList()}//消息列表asyncfunctiongetMyExamList(){constref=awaitgetMyExamListService(params.value)myExamList.value=ref.rows total.value=ref.total}getMyExamList()functionisHistoryExam(exam){constnow=newDate();returnnewDate(exam.endTime)<now;}constisNotStart=(exam)=>{constnow=newDate();//当前时间returnnewDate(exam.startTime)>now;}constgoBack=()=>{router.go(-1)}</script><stylelang="scss">.my-exam-page{max-width:1520px;margin:0 auto;background-color:rgba(247,247,247,1);position:relative;overflow:hidden;display:flex;justify-content:center;}.exam-list-block{width:100%;display:flex;flex-wrap:wrap;}.exam-list-header{background-color:rgba(255,255,255,1);border-radius:10px;width:100%;/* 设置宽度为100%以确保水平居中 */height:60px;font-size:25px;text-indent:20px;display:flex;align-items:center;margin-top:20px;.ex-title{font-family:PingFangSC,PingFang SC;font-weight:600;font-size:18px;color:#222222;}.exam-list-back{cursor:pointer;color:#999999;font-size:15px;margin-left:auto;padding-right:20px;}}.exam-list-content{height:110px;width:100%;background:#FFFFFF;border-radius:10px;margin:0 auto;display:flex;align-items:center;margin-top:20px;justify-content:space-between;cursor:pointer;&:hover{box-shadow:0px 0px 6px 0pxrgba(0,0,0,0.1);}img{width:50px;height:50px;margin:0 20px;}}.exam-list-content .exam-content{max-width:calc(100% - 320px);width:100%;}.exam-list-content .title{font-weight:bold;font-size:16px;margin-bottom:10px;}.exam-list-content .date{font-weight:400;color:#000;line-height:20px;margin-left:auto;font-size:14px;span{color:#999;}/* 将日期推至行尾 */}.exam-list-content .exam-status-lable{color:#999999;}.exam-end-lable-list{padding-right:20px;min-width:228px;text-align:right;.exam-end-lable{margin-right:10px;font-family:MicrosoftYaHei;font-size:16px;color:#999999;}.exam-rank-lable{font-size:16px;}}.my-exam-pagination{width:100%;display:flex;justify-content:flex-end;padding-bottom:20px;}</style>
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进