2026/10/19 1:34:37

【项目】【在线判题系统】b端题目增删改

【项目】【在线判题系统】b端题目增删改 目录一、新增题目1.1、功能梳理1.2 controller1.3 service二、题目编辑2.1 功能梳理2.2 获取题目详情2.2.1 controller2.2.2 service2.3 修改题目2.3.1 controller2.3.2 service三、题目删除3.1 功能梳理3.2 controller3.3 service四、题目前端总代码一、新增题目1.1、功能梳理登录登录成功之后切换至题目管理点击添加题目按钮弹出抽屉。根据所要添加的题目输入题目的相关信息点击发布。将用户输入的题目信息作为请求参数向后端发起添加题目的请求。后端接收请求对请求参数处理。将数据存储到数据库中。后端需要将题目添加的结果返回给前端。前端接收到端的响应如果成功:提示用户添加成功并且在列表中将新增的题目展示在 第一个8如果失败:失败原因提示给用户1.2 controlleroj-modules/oj-system/src/main/java/com/yj/system/controller/question/QuestionController.java添加新增方法PostMapping(/add)publicRVoidadd(RequestBodyValidatedQuestionAddDTOquestionAddDTO){returntoR(questionService.add(questionAddDTO));}接收请求参数oj-modules/oj-system/src/main/java/com/yj/system/domain/question/dto/QuestionAddDTO.javapackagecom.yj.system.domain.question.dto;importjakarta.validation.constraints.NotBlank;importjakarta.validation.constraints.NotNull;importjakarta.validation.constraints.Positive;importjakarta.validation.constraints.Max;importjakarta.validation.constraints.Min;importlombok.Getter;importlombok.Setter;/** * 题目新增请求参数 DTO */GetterSetterpublicclassQuestionAddDTO{/** * 题目标题 */NotBlank(message题目标题不能为空)privateStringtitle;/** * 题目难度 1简单 2中等 3困难 */NotNull(message题目难度不能为空)Min(value1,message题目难度只能是 1、2、3)Max(value3,message题目难度只能是 1、2、3)privateIntegerdifficulty;/** * 时间限制单位ms */NotNull(message时间限制不能为空)Positive(message时间限制必须为正整数)privateIntegertimeLimit;/** * 空间限制单位MB */NotNull(message空间限制不能为空)Positive(message空间限制必须为正整数)privateIntegerspaceLimit;/** * 题目内容 */NotBlank(message题目内容不能为空)privateStringcontent;/** * 题目用例 */NotBlank(message题目用例不能为空)privateStringquestionCase;/** * 默认代码块 */NotBlank(message默认代码不能为空)privateStringdefaultCode;/** * 主函数代码 */NotBlank(messagemain函数不能为空)privateStringmainFuc;}1.3 serviceoj-modules/oj-system/src/main/java/com/yj/system/service/question/IQuestionService.java新增接口方法intadd(QuestionAddDTOquestionAddDTO);实现接口方法查询标题或者内容有相同的数据没有没有就进行转换数据插入数据库有就抛出资源已存在的异常。oj-modules/oj-system/src/main/java/com/yj/system/service/question/impl/QuestionServiceImpl.javaOverridepublicintadd(QuestionAddDTOquestionAddDTO){// 1.构建查询条件标题 或 内容 重复ListQuestionDOquestionDOSquestionMapper.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. 拷贝属性并插入QuestionDOquestionDOnewQuestionDO();BeanUtils.copyProperties(questionAddDTO,questionDO);// 4. 插入数据库returnquestionMapper.insert(questionDO);}二、题目编辑2.1 功能梳理题目编辑功能:对需要编辑的题目点击编辑按钮。携带题目id向后端发起获取题目详情的请求。后端接收到获取题目详情的请求之后根据题目id从数据库中查询出题目详情并将查询结果返回给前端展示。(如果查询失败编辑题目流程结束提示给用户失败的原因)根据展示出来的题目详情和对于题目的修改需要对题目的具体信息进行修改。点击发布。携带题目id以及修改之后的内容向后端发起编辑题目的请求。后端接收编辑题目的请求之后根据题目的id从数据库中查到对应的题目然后再根据修改之后的题目内容修改数据中存储的题目数据。并且将修改之后的结果返回给前端。前端接收到后端返回的响应结果之后如果成功提示用户编辑成功并且再去查看这个题目的信息的时候应该是修改之后的。如果失败提示给用户失败的原因。2.2 获取题目详情2.2.1 controlleroj-modules/oj-system/src/main/java/com/yj/system/controller/question/QuestionController.java添加方法根据题目id获得题目信息GetMapping(/detail)publicRQuestionDetailVOdetail(LongquestionId){QuestionDetailVOdetailquestionService.detail(questionId);returnR.success(detail);}返回值oj-modules/oj-system/src/main/java/com/yj/system/domain/question/vo/QuestionDetailVO.javapackagecom.yj.system.domain.question.vo;importlombok.Getter;importlombok.Setter;GetterSetterpublicclassQuestionDetailVO{/** * 题目id主键 */privateLongquestionId;/** * 题目标题 */privateStringtitle;/** * 题目难度 1简单 2中等 3困难 */privateIntegerdifficulty;/** * 时间限制 */privateIntegertimeLimit;/** * 空间限制 */privateIntegerspaceLimit;/** * 题目内容 */privateStringcontent;/** * 题目用例 */privateStringquestionCase;/** * 默认代码 */privateStringdefaultCode;/** * main函数 */privateStringmainFuc;}2.2.2 serviceoj-modules/oj-system/src/main/java/com/yj/system/service/question/IQuestionService.java定义接口方法QuestionDetailVOdetail(LongquestionId);oj-modules/oj-system/src/main/java/com/yj/system/service/question/impl/QuestionServiceImpl.java实现接口方法查询数据库如果没有数据抛异常有进行转化返回。OverridepublicQuestionDetailVOdetail(LongquestionId){QuestionDOquestionDOquestionMapper.selectById(questionId);if(nullquestionDO){thrownewServiceException(ResultCodeEnum.FAILED_NOT_EXISTS);}QuestionDetailVOquestionDetailVOnewQuestionDetailVO();BeanUtils.copyProperties(questionDO,questionDetailVO);returnquestionDetailVO;}2.3 修改题目2.3.1 controlleroj-modules/oj-system/src/main/java/com/yj/system/controller/question/QuestionController.java添加方法PutMapping(/edit)publicRVoidedit(RequestBodyValidatedQuestionEditDTOquestionEditDTO){returntoR(questionService.edit(questionEditDTO));}接收参数oj-modules/oj-system/src/main/java/com/yj/system/domain/question/dto/QuestionEditDTO.javapackagecom.yj.system.domain.question.dto;importjakarta.validation.constraints.*;importlombok.Getter;importlombok.Setter;/** * 题目新增请求参数 DTO */GetterSetterpublicclassQuestionEditDTOextendsQuestionAddDTO{NotBlank(message题目id不能为空)privateLongquestionId;}2.3.2 serviceoj-modules/oj-system/src/main/java/com/yj/system/service/question/IQuestionService.java定义接口方法intedit(QuestionEditDTOquestionEditDTO);oj-modules/oj-system/src/main/java/com/yj/system/service/question/impl/QuestionServiceImpl.java实现接口方法Overridepublicintedit(QuestionEditDTOquestionEditDTO){// 1. 判断题目是否存在QuestionDOquestionDOquestionMapper.selectById(questionEditDTO.getQuestionId());if(nullquestionDO){thrownewServiceException(ResultCodeEnum.FAILED_NOT_EXISTS);}// 2. 判断标题/内容是否与其他题目重复排除自身ListQuestionDOlistquestionMapper.selectList(Wrappers.lambdaQuery(QuestionDO.class).and(w-w.eq(QuestionDO::getTitle,questionEditDTO.getTitle()).or().eq(QuestionDO::getContent,questionEditDTO.getContent())).ne(QuestionDO::getQuestionId,questionEditDTO.getQuestionId()));if(CollectionUtil.isNotEmpty(list)){thrownewServiceException(ResultCodeEnum.FAILED_ALREADY_EXISTS);}// 3. 赋值questionDO.setTitle(questionEditDTO.getTitle());questionDO.setDifficulty(questionEditDTO.getDifficulty());questionDO.setTimeLimit(questionEditDTO.getTimeLimit());questionDO.setSpaceLimit(questionEditDTO.getSpaceLimit());questionDO.setContent(questionEditDTO.getContent());questionDO.setQuestionCase(questionEditDTO.getQuestionCase());questionDO.setDefaultCode(questionEditDTO.getDefaultCode());questionDO.setMainFuc(questionEditDTO.getMainFuc());// 4. 修改returnquestionMapper.updateById(questionDO);}三、题目删除3.1 功能梳理题目删除功能:找到要删除的题目点击删除按钮。前端携带着题目id向后端发起删除题目的请求。后端接收到请求之后根据题目id删除题目。并将删除的结果返回给前端。(成功或者失败)前端接收后端响应之后如果成功提示用户删除成功并将删除的题目从题目列表中移除。如果失败提示用户失败原因。3.2 controlleroj-modules/oj-system/src/main/java/com/yj/system/controller/question/QuestionController.java添加方法DeleteMapping(/delete)publicRVoiddelete(LongquestionId){returntoR(questionService.delete(questionId));}3.3 serviceoj-modules/oj-system/src/main/java/com/yj/system/service/question/IQuestionService.java定义接口方法intdelete(LongquestionId);oj-modules/oj-system/src/main/java/com/yj/system/service/question/impl/QuestionServiceImpl.java实现接口方法Overridepublicintdelete(LongquestionId){// 1. 判断题目是否存在QuestionDOquestionDOquestionMapper.selectById(questionId);if(nullquestionDO){thrownewServiceException(ResultCodeEnum.FAILED_NOT_EXISTS);}returnquestionMapper.deleteById(questionId);}四、题目前端总代码templateel-form inlinetrueel-form-itemselector v-modelparams.difficultyplaceholder请选择题目难度stylewidth: 200px;/selector/el-form-itemel-form-itemel-input v-modelparams.titleplaceholder请您输入要搜索的题目标题//el-form-itemel-form-itemel-button plainClickonSearch搜索/el-buttonel-button plain typeinfoclickonReset重置/el-buttonel-button plain typeprimary:iconPlusclickonAddQuestion添加题目/el-button/el-form-item/el-formel-table height526px:dataquestionListel-table-column propquestionIdwidth180pxlabel题目id/el-table-column proptitlelabel题目标题/el-table-column propdifficultylabel题目难度width90pxtemplate #default{ row }div v-ifrow.difficulty 1stylecolor:#3EC8FF;简单/divdiv v-ifrow.difficulty 2stylecolor:#FE7909;中等/divdiv v-ifrow.difficulty 3stylecolor:#FD4C40;困难/div/template/el-table-columnel-table-column propcreateNamelabel创建人width140px/el-table-column propcreateTimelabel创建时间width180px/el-table-column label操作width100pxfixedrighttemplate #default{ row }el-button typetextclickonEdit(row.questionId)编辑/el-buttonel-button typetextclassredclickonDelete(row.questionId)删除/el-button/template/el-table-column/el-tableel-pagination background sizesmalllayouttotal, sizes, prev, pager, next, jumper:totaltotalv-model:current-pageparams.pageNumv-model:page-sizeparams.pageSize:page-sizes[1, 5, 10, 15, 20]size-changehandleSizeChangecurrent-changehandleCurrentChange/question-drawer refquestionEditRefsuccessonSuccess/question-drawer/templatescript setupimport{Plus}fromelement-plus/icons-vueimportSelectorfrom/components/QuestionSelector.vueimport{getQuestionListService,delQuestionService}from/apis/questionimport{reactive,ref}fromvue;importQuestionDrawerfrom/components/QuestionDrawer.vueconstparamsreactive({pageNum:1,pageSize:10,difficulty:,title:})constquestionListref([])consttotalref(0)async functiongetQuestionList(){constresultawaitgetQuestionListService(params)console.log(result)questionList.valueresult.rows total.valueresult.total}getQuestionList()functionhandleSizeChange(newSize){// params.pageSize newSizeparams.pageNum1getQuestionList()}functionhandleCurrentChange(newPage){// params.pageNum newPagegetQuestionList()}functiononSearch(){params.pageNum1getQuestionList()}functiononReset(){params.pageNum1params.pageSize10params.title params.difficultygetQuestionList()}constquestionEditRefref()// 添加constonAddQuestion(){questionEditRef.value.open()}functiononSuccess(service){if(serviceadd){params.pageNum1}getQuestionList()}async functiononEdit(questionId){questionEditRef.value.open(questionId)}async functiononDelete(questionId){awaitdelQuestionService(questionId)params.pageNum1getQuestionList()}/script