feat: 练题模块完成

This commit is contained in:
2024-04-06 21:04:38 +08:00
parent 43d3a2a6d5
commit 8d1fcf0401
114 changed files with 3667 additions and 21 deletions

View File

@@ -15,7 +15,7 @@
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<maven.compiler.target>8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

View File

@@ -15,7 +15,7 @@
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<maven.compiler.target>8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

View File

@@ -2,8 +2,6 @@ package com.landaiqing.club.gateway.auth;
import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.reactor.filter.SaReactorFilter;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpUtil;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -25,9 +23,9 @@ public class SaTokenConfigure {
System.out.println("-------- 前端访问path" + SaHolder.getRequest().getRequestPath());
// 登录校验 -- 拦截所有路由,并排除/user/doLogin 用于开放登录
//SaRouter.match("/auth/**", "/auth/user/doLogin", r -> StpUtil.checkRole("admin"));
SaRouter.match("/oss/**", r -> StpUtil.checkLogin());
SaRouter.match("/subject/subject/add", r -> StpUtil.checkPermission("subject:add"));
SaRouter.match("/subject/**", r -> StpUtil.checkLogin());
// SaRouter.match("/oss/**", r -> StpUtil.checkLogin());
// SaRouter.match("/subject/subject/add", r -> StpUtil.checkPermission("subject:add"));
// SaRouter.match("/subject/**", r -> StpUtil.checkLogin());
})
;
}

View File

@@ -31,7 +31,7 @@ public class LoginFilter implements GlobalFilter {
ServerHttpRequest.Builder mutate = request.mutate();
String url = request.getURI().getPath();
log.info("LoginFilter.filter.url:{}", url);
if (url.equals("/auth/user/doLogin") || url.equals("/auth/user/getUserInfo")) {
if (url.equals("/user/doLogin") || url.equals("/user/getUserInfo")) {
return chain.filter(exchange);
}
SaTokenInfo tokenInfo = StpUtil.getTokenInfo();

View File

@@ -3,12 +3,12 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.landaiqing</groupId>
<artifactId>qing-yu-practice</artifactId>
<artifactId>qing-yu-club-practice</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>qing-yu-practice-api</module>
<module>qing-yu-practice-server</module>
<module>qing-yu-club-practice-api</module>
<module>qing-yu-club-practice-server</module>
</modules>

View File

@@ -3,11 +3,11 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.landaiqing</groupId>
<artifactId>qing-yu-practice</artifactId>
<artifactId>qing-yu-club-practice</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>qing-yu-practice-api</artifactId>
<artifactId>qing-yu-club-practice-api</artifactId>
<packaging>jar</packaging>

View File

@@ -0,0 +1,30 @@
package com.landaiqing.practice.api.enums;
public enum AnswerStatusEnum {
/**
* 错误
*/
ERROR(0, "错误"),
/**
* 正确
*/
CORRECT(1, "正确");
final private int code;
final private String desc;
AnswerStatusEnum(int code, String desc) {
this.code = code;
this.desc = desc;
}
public int getCode() {
return code;
}
public String getDesc() {
return desc;
}
}

View File

@@ -0,0 +1,30 @@
package com.landaiqing.practice.api.enums;
public enum CompleteStatusEnum {
/**
* 未完成
*/
NO_COMPLETE(0, "未完成"),
/**
* 已完成
*/
COMPLETE(1, "已完成");
final private int code;
final private String desc;
CompleteStatusEnum(int code, String desc) {
this.code = code;
this.desc = desc;
}
public int getCode() {
return code;
}
public String getDesc() {
return desc;
}
}

View File

@@ -0,0 +1,30 @@
package com.landaiqing.practice.api.enums;
public enum SetTypeEnum {
/**
* 实时生成
*/
REAL(1, "实时生成"),
/**
* 预设套题
*/
PRESET(2, "预设套题");
final private int code;
final private String desc;
SetTypeEnum(int code, String desc) {
this.code = code;
this.desc = desc;
}
public int getCode() {
return code;
}
public String getDesc() {
return desc;
}
}

View File

@@ -0,0 +1,37 @@
package com.landaiqing.practice.api.enums;
import lombok.Getter;
/**
* 题目类型枚举
* 1单选 2多选 3判断 4简答
* @author: landaiqing
*/
@Getter
public enum SubjectInfoTypeEnum {
RADIO(1,"单选"),
MULTIPLE(2,"多选"),
JUDGE(3,"判断"),
BRIEF(4,"简答"),
;
public int code;
public String desc;
SubjectInfoTypeEnum(int code, String desc){
this.code = code;
this.desc = desc;
}
public static SubjectInfoTypeEnum getByCode(int codeVal){
for(SubjectInfoTypeEnum resultCodeEnum : SubjectInfoTypeEnum.values()){
if(resultCodeEnum.code == codeVal){
return resultCodeEnum;
}
}
return null;
}
}

View File

@@ -0,0 +1,16 @@
package com.landaiqing.practice.api.req;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class GetPracticeSubjectListReq implements Serializable {
/**
* 分类与标签组合的ids
*/
private List<String> assembleIds;
}

View File

@@ -0,0 +1,20 @@
package com.landaiqing.practice.api.req;
import lombok.Data;
import java.io.Serializable;
@Data
public class GetPracticeSubjectReq implements Serializable {
/**
* 题目id
*/
private Long subjectId;
/**
* 题目类型
*/
private Integer subjectType;
}

View File

@@ -0,0 +1,20 @@
package com.landaiqing.practice.api.req;
import lombok.Data;
import java.io.Serializable;
@Data
public class GetPracticeSubjectsReq implements Serializable {
/**
* 套题id
*/
private Long setId;
/**
* 练习id
*/
private Long practiceId;
}

View File

@@ -0,0 +1,26 @@
package com.landaiqing.practice.api.req;
import com.landaiqing.practice.api.common.PageInfo;
import lombok.Data;
import java.io.Serializable;
@Data
public class GetPreSetReq implements Serializable {
/**
* 排序类型 1默认 2最新 3最热
*/
private Integer orderType;
/**
* 分页信息
*/
private PageInfo pageInfo;
/**
* 套题名称
*/
private String setName;
}

View File

@@ -0,0 +1,15 @@
package com.landaiqing.practice.api.req;
import lombok.Data;
import java.io.Serializable;
@Data
public class GetReportReq implements Serializable {
/**
* 练习id
*/
private Long practiceId;
}

View File

@@ -0,0 +1,15 @@
package com.landaiqing.practice.api.req;
import lombok.Data;
import java.io.Serializable;
@Data
public class GetScoreDetailReq implements Serializable {
/**
* 练习id
*/
private Long practiceId;
}

View File

@@ -0,0 +1,25 @@
package com.landaiqing.practice.api.req;
import lombok.Data;
import java.io.Serializable;
@Data
public class GetSubjectDetailReq implements Serializable {
/**
* 练习id
*/
private Long practiceId;
/**
* 题目id
*/
private Long subjectId;
/**
* 题目类型
*/
private Integer subjectType;
}

View File

@@ -0,0 +1,16 @@
package com.landaiqing.practice.api.req;
import com.landaiqing.practice.api.common.PageInfo;
import lombok.Data;
import java.io.Serializable;
@Data
public class GetUnCompletePracticeReq implements Serializable {
/**
* 分页信息
*/
private PageInfo pageInfo;
}

View File

@@ -0,0 +1,31 @@
package com.landaiqing.practice.api.req;
import lombok.Data;
import java.io.Serializable;
@Data
public class SubmitPracticeDetailReq implements Serializable {
/**
* 套题id
*/
private Long setId;
/**
* 练习id
*/
private Long practiceId;
/**
* 用时
*/
private String timeUse;
/**
* 交卷时间
*/
private String submitTime;
}

View File

@@ -0,0 +1,36 @@
package com.landaiqing.practice.api.req;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class SubmitSubjectDetailReq implements Serializable {
/**
* 练习id
*/
private Long practiceId;
/**
* 题目id
*/
private Long subjectId;
/**
* 题目答案
*/
private List<Integer> answerContents;
/**
* 题目类型
*/
private Integer subjectType;
/**
* 用时
*/
private String timeUse;
}

View File

@@ -0,0 +1,30 @@
package com.landaiqing.practice.api.vo;
import lombok.Data;
import java.io.Serializable;
@Data
public class PracticeSetVO implements Serializable {
/**
* 套题id
*/
private Long setId;
/**
* 套题名称
*/
private String setName;
/**
* 套题热度
*/
private Integer setHeat;
/**
* 套题描述
*/
private String setDesc;
}

View File

@@ -0,0 +1,25 @@
package com.landaiqing.practice.api.vo;
import lombok.Data;
import java.io.Serializable;
@Data
public class PracticeSubjectDetailVO implements Serializable {
/**
* 题目id
*/
private Long subjectId;
/**
* 题目类型
*/
private Integer subjectType;
/**
* 是否回答
*/
private Integer isAnswer;
}

View File

@@ -0,0 +1,31 @@
package com.landaiqing.practice.api.vo;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class PracticeSubjectListVO implements Serializable {
/**
* 练习标题
*/
private String title;
/**
* 题目列表
*/
private List<PracticeSubjectDetailVO> subjectList;
/**
* 练习id
*/
private Long practiceId;
/**
* 用时
*/
private String timeUse;
}

View File

@@ -0,0 +1,25 @@
package com.landaiqing.practice.api.vo;
import lombok.Data;
import java.io.Serializable;
@Data
public class PracticeSubjectOptionVO implements Serializable {
/**
* 答案类型
*/
private Integer optionType;
/**
* 答案内容
*/
private String optionContent;
/**
* 是否正確
*/
private Integer isCorrect;
}

View File

@@ -0,0 +1,31 @@
package com.landaiqing.practice.api.vo;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class PracticeSubjectVO implements Serializable {
/**
* 题目名称
*/
private String subjectName;
/**
* 题目类型
*/
private Integer subjectType;
/**
* 答案列表
*/
private List<String> answerContentList;
/**
* 单选、多选、判断题目答案
*/
private List<PracticeSubjectOptionVO> optionList;
}

View File

@@ -0,0 +1,26 @@
package com.landaiqing.practice.api.vo;
import lombok.Data;
import java.io.Serializable;
@Data
public class RankVO implements Serializable {
/**
* 头像
*/
private String avatar;
/**
* 名称
*/
private String name;
/**
* 练习数量
*/
private Integer count;
}

View File

@@ -0,0 +1,21 @@
package com.landaiqing.practice.api.vo;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
@Data
public class ReportSkillVO implements Serializable {
/**
* 分数
*/
private BigDecimal star;
/**
* 名称
*/
private String name;
}

View File

@@ -0,0 +1,26 @@
package com.landaiqing.practice.api.vo;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class ReportVO implements Serializable {
/**
* 试卷题目
*/
private String title;
/**
* 正确题目数
*/
private String correctSubject;
/**
* 技能图谱
*/
private List<ReportSkillVO> skill;
}

View File

@@ -0,0 +1,26 @@
package com.landaiqing.practice.api.vo;
import lombok.Data;
import java.io.Serializable;
@Data
public class ScoreDetailVO implements Serializable {
/**
* 题目id
*/
private Long subjectId;
/**
* 题目类型
*/
private Integer subjectType;
/**
* 是否正确
*/
private Integer isCorrect;
}

View File

@@ -0,0 +1,17 @@
package com.landaiqing.practice.api.vo;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class SpecialPracticeCategoryVO implements Serializable {
private String categoryName;
private Long categoryId;
private List<SpecialPracticeLabelVO> labelList;
}

View File

@@ -0,0 +1,19 @@
package com.landaiqing.practice.api.vo;
import lombok.Data;
import java.io.Serializable;
@Data
public class SpecialPracticeLabelVO implements Serializable {
private Long id;
/**
* 分类id-标签ID
*/
private String assembleId;
private String labelName;
}

View File

@@ -0,0 +1,17 @@
package com.landaiqing.practice.api.vo;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class SpecialPracticeVO implements Serializable {
private String primaryCategoryName;
private Long primaryCategoryId;
private List<SpecialPracticeCategoryVO> categoryList;
}

View File

@@ -0,0 +1,41 @@
package com.landaiqing.practice.api.vo;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class SubjectDetailVO implements Serializable {
/**
* 正确答案
*/
private List<Integer> correctAnswer;
/**
* 答题者答案
*/
private List<Integer> respondAnswer;
/**
* 题目解析
*/
private String subjectParse;
/**
* 答案详情
*/
private List<PracticeSubjectOptionVO> optionList;
/**
* 涉及的标签
*/
private List<String> labelNames;
/**
* 题目名称
*/
private String subjectName;
}

View File

@@ -0,0 +1,30 @@
package com.landaiqing.practice.api.vo;
import lombok.Data;
import java.io.Serializable;
@Data
public class UnCompletePracticeSetVO implements Serializable {
/**
* 套题id
*/
private Long setId;
/**
* 练习id
*/
private Long practiceId;
/**
* 练习时间
*/
private String practiceTime;
/**
* 套题名称
*/
private String title;
}

View File

@@ -3,11 +3,11 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.landaiqing</groupId>
<artifactId>qing-yu-practice</artifactId>
<artifactId>qing-yu-club-practice</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>qing-yu-practice-server</artifactId>
<artifactId>qing-yu-club-practice-server</artifactId>
<packaging>jar</packaging>
<name>qing-yu-practice-server</name>
@@ -120,7 +120,16 @@
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.landaiqing</groupId>
<artifactId>qing-yu-club-practice-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.landaiqing</groupId>
<artifactId>qing-yu-club-auth-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<dependencyManagement>

View File

@@ -0,0 +1,194 @@
package com.landaiqing.practice.server.controller;
import com.alibaba.fastjson.JSON;
import com.google.common.base.Preconditions;
import com.landaiqing.practice.api.common.Result;
import com.landaiqing.practice.api.req.*;
import com.landaiqing.practice.api.vo.RankVO;
import com.landaiqing.practice.api.vo.ReportVO;
import com.landaiqing.practice.api.vo.ScoreDetailVO;
import com.landaiqing.practice.api.vo.SubjectDetailVO;
import com.landaiqing.practice.server.service.PracticeDetailService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
@RestController
@Slf4j
@RequestMapping("/practice/detail")
public class PracticeDetailController {
@Resource
private PracticeDetailService practiceDetailService;
/**
* 提交题目
*/
@PostMapping(value = "/submitSubject")
public Result<Boolean> submitSubject(@RequestBody SubmitSubjectDetailReq req) {
try {
if (log.isInfoEnabled()) {
log.info("练习提交题目入参{}", JSON.toJSONString(req));
}
Preconditions.checkArgument(!Objects.isNull(req), "参数不能为空!");
Preconditions.checkArgument(!Objects.isNull(req.getPracticeId()), "练习id不能为空");
Preconditions.checkArgument(!Objects.isNull(req.getSubjectId()), "题目id不能为空");
Preconditions.checkArgument(!Objects.isNull(req.getSubjectType()), "题目类型不能为空!");
Preconditions.checkArgument(!StringUtils.isBlank(req.getTimeUse()), "用时不能为空!");
Boolean result = practiceDetailService.submitSubject(req);
log.info("练习提交题目出参{}", result);
return Result.ok(result);
} catch (IllegalArgumentException e) {
log.error("参数异常!错误原因{}", e.getMessage(), e);
return Result.fail(e.getMessage());
} catch (Exception e) {
log.error("练习提交题目异常!错误原因{}", e.getMessage(), e);
return Result.fail("练习提交题目异常!");
}
}
/**
* 提交练题情况
*/
@PostMapping(value = "/submit")
public Result<Boolean> submit(@RequestBody SubmitPracticeDetailReq req) {
try {
if (log.isInfoEnabled()) {
log.info("提交练题情况入参{}", JSON.toJSONString(req));
}
Preconditions.checkArgument(!Objects.isNull(req), "参数不能为空!");
Preconditions.checkArgument(!Objects.isNull(req.getSetId()), "套题id不能为空");
Preconditions.checkArgument(!StringUtils.isBlank(req.getSubmitTime()), "交卷时间不能为空!");
Preconditions.checkArgument(!StringUtils.isBlank(req.getTimeUse()), "用时不能为空!");
Boolean result = practiceDetailService.submit(req);
if (log.isInfoEnabled()) {
log.info("提交练题情况出参{}", JSON.toJSONString(result));
}
return Result.ok(result);
} catch (IllegalArgumentException e) {
log.error("参数异常!错误原因{}", e.getMessage(), e);
return Result.fail(e.getMessage());
} catch (Exception e) {
log.error("提交练题情况异常!错误原因{}", e.getMessage(), e);
return Result.fail("提交练题情况异常!");
}
}
/**
* 答案解析-每题得分
*/
@PostMapping(value = "/getScoreDetail")
public Result<List<ScoreDetailVO>> getScoreDetail(@RequestBody GetScoreDetailReq req) {
try {
if (log.isInfoEnabled()) {
log.info("每题得分入参{}", JSON.toJSONString(req));
}
Preconditions.checkArgument(!Objects.isNull(req), "参数不能为空!");
Preconditions.checkArgument(!Objects.isNull(req.getPracticeId()), "练习id不能为空");
List<ScoreDetailVO> list = practiceDetailService.getScoreDetail(req);
if (log.isInfoEnabled()) {
log.info("每题得分出参{}", JSON.toJSONString(list));
}
return Result.ok(list);
} catch (IllegalArgumentException e) {
log.error("参数异常!错误原因{}", e.getMessage(), e);
return Result.fail(e.getMessage());
} catch (Exception e) {
log.error("每题得分异常!错误原因{}", e.getMessage(), e);
return Result.fail("每题得分异常!");
}
}
/**
* 答案解析-答题详情
*/
@PostMapping(value = "/getSubjectDetail")
public Result<SubjectDetailVO> getSubjectDetail(@RequestBody GetSubjectDetailReq req) {
try {
if (log.isInfoEnabled()) {
log.info("答案详情入参{}", JSON.toJSONString(req));
}
Preconditions.checkArgument(!Objects.isNull(req), "参数不能为空!");
Preconditions.checkArgument(!Objects.isNull(req.getSubjectId()), "题目id不能为空");
Preconditions.checkArgument(!Objects.isNull(req.getSubjectType()), "题目类型不能为空!");
SubjectDetailVO subjectDetailVO = practiceDetailService.getSubjectDetail(req);
if (log.isInfoEnabled()) {
log.info("答案详情出参{}", JSON.toJSONString(subjectDetailVO));
}
return Result.ok(subjectDetailVO);
} catch (IllegalArgumentException e) {
log.error("参数异常!错误原因{}", e.getMessage(), e);
return Result.fail(e.getMessage());
} catch (Exception e) {
log.error("答案详情异常!错误原因{}", e.getMessage(), e);
return Result.fail("答案详情异常!");
}
}
/**
* 答案解析-评估报告
*/
@PostMapping(value = "/getReport")
public Result<ReportVO> getReport(@RequestBody GetReportReq req) {
try {
if (log.isInfoEnabled()) {
log.info("获取评估报告入参{}", JSON.toJSONString(req));
}
Preconditions.checkArgument(!Objects.isNull(req), "参数不能为空!");
Preconditions.checkArgument(!Objects.isNull(req.getPracticeId()), "练习id不能为空");
ReportVO reportVO = practiceDetailService.getReport(req);
if (log.isInfoEnabled()) {
log.info("获取评估报告出参{}", JSON.toJSONString(reportVO));
}
return Result.ok(reportVO);
} catch (IllegalArgumentException e) {
log.error("参数异常!错误原因{}", e.getMessage(), e);
return Result.fail(e.getMessage());
} catch (Exception e) {
log.error("获取评估报告异常!错误原因{}", e.getMessage(), e);
return Result.fail("获取评估报告异常!");
}
}
/**
* 获取练习榜
*/
@PostMapping(value = "/getPracticeRankList")
public Result<List<RankVO>> getPracticeRankList() {
try {
List<RankVO> list = practiceDetailService.getPracticeRankList();
if (log.isInfoEnabled()) {
log.info("练习榜出参{}", list);
}
return Result.ok(list);
} catch (Exception e) {
log.error("练习榜报错!错误原因{}", e.getMessage(), e);
return Result.fail("练习榜异常!");
}
}
/**
* 放弃练习
*/
@PostMapping(value = "/giveUp")
public Result<Boolean> giveUp(@RequestParam("practiceId") Long practiceId) {
try {
log.info("放弃练习入参{}", practiceId);
Preconditions.checkArgument(!Objects.isNull(practiceId), "练习id不能为空");
Boolean result = practiceDetailService.giveUp(practiceId);
log.info("放弃练习出参{}", result);
return Result.ok(result);
} catch (IllegalArgumentException e) {
log.error("参数异常!错误原因{}", e.getMessage(), e);
return Result.fail(e.getMessage());
} catch (Exception e) {
log.error("放弃练习异常!错误原因{}", e.getMessage(), e);
return Result.fail("放弃练习异常!");
}
}
}

View File

@@ -0,0 +1,184 @@
package com.landaiqing.practice.server.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.google.common.base.Preconditions;
import com.landaiqing.practice.api.common.PageResult;
import com.landaiqing.practice.api.common.Result;
import com.landaiqing.practice.api.req.*;
import com.landaiqing.practice.api.vo.*;
import com.landaiqing.practice.server.entity.dto.PracticeSetDTO;
import com.landaiqing.practice.server.entity.dto.PracticeSubjectDTO;
import com.landaiqing.practice.server.service.PracticeSetService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
/**
* @Classname PracticeSetController
* @BelongsProject: qing-yu-club
* @BelongsPackage: com.landaiqing.practice.server.controller
* @Author: landaiqing
* @CreateTime: 2024-03-12 17:22
* @Description: TODO
* @Version: 1.0
*/
@RestController
@Slf4j
@RequestMapping("/practice/set/")
public class PracticeSetController {
@Resource
private PracticeSetService practiceSetService;
@RequestMapping("getSpecialPracticeContent")
public Result<List<SpecialPracticeVO>> getSpecialPracticeContent() {
try {
List<SpecialPracticeVO> result = practiceSetService.getSpecialPracticeContent();
if (log.isInfoEnabled()) {
log.info("PracticeSetController.getSpecialPracticeContent.result: {}", JSON.toJSONString(result));
}
return Result.ok(result);
} catch (Exception e) {
log.error("PracticeSetController.getSpecialPracticeContent.error: {}", e.getMessage(), e);
return Result.fail("获取专项练习内容失败!");
}
}
/**
* 开始练习
*/
@PostMapping(value = "/addPractice")
public Result<PracticeSetVO> addPractice(@RequestBody GetPracticeSubjectListReq req) {
if (log.isInfoEnabled()) {
log.info("获取练习题入参{}", JSON.toJSONString(req));
}
try {
//参数校验
Preconditions.checkArgument(!Objects.isNull(req), "参数不能为空!");
Preconditions.checkArgument(!CollectionUtils.isEmpty(req.getAssembleIds()), "标签ids不能为空");
PracticeSubjectDTO dto = new PracticeSubjectDTO();
dto.setAssembleIds(req.getAssembleIds());
PracticeSetVO practiceSetVO = practiceSetService.addPractice(dto);
if (log.isInfoEnabled()) {
log.info("获取练习题目列表出参{}", JSON.toJSONString(practiceSetVO));
}
return Result.ok(practiceSetVO);
} catch (IllegalArgumentException e) {
log.error("参数异常!错误原因{}", e.getMessage(), e);
return Result.fail(e.getMessage());
} catch (Exception e) {
log.error("获取练习题目列表异常!错误原因{}", e.getMessage(), e);
return Result.fail("获取练习题目列表异常!");
}
}
/**
* 获取练习题
*/
@PostMapping(value = "/getSubjects")
public Result<PracticeSubjectListVO> getSubjects(@RequestBody GetPracticeSubjectsReq req) {
if (log.isInfoEnabled()) {
log.info("获取练习题入参{}", JSON.toJSONString(req));
}
try {
Preconditions.checkArgument(!Objects.isNull(req), "参数不能为空!");
Preconditions.checkArgument(!Objects.isNull(req.getSetId()), "练习id不能为空");
PracticeSubjectListVO list = practiceSetService.getSubjects(req);
if (log.isInfoEnabled()) {
log.info("获取练习题目列表出参{}", JSON.toJSONString(list));
}
return Result.ok(list);
} catch (IllegalArgumentException e) {
log.error("参数异常!错误原因{}", e.getMessage(), e);
return Result.fail(e.getMessage());
} catch (Exception e) {
log.error("获取练习题目列表异常!错误原因{}", e.getMessage(), e);
return Result.fail("获取练习题目列表异常!");
}
}
/**
* 获取题目详情
*/
@PostMapping(value = "/getPracticeSubject")
public Result<PracticeSubjectVO> getPracticeSubject(@RequestBody GetPracticeSubjectReq req) {
if (log.isInfoEnabled()) {
log.info("获取练习题详情入参{}", JSON.toJSONString(req));
}
try {
Preconditions.checkArgument(!Objects.isNull(req), "参数不能为空!");
Preconditions.checkArgument(!Objects.isNull(req.getSubjectId()), "题目id不能为空");
Preconditions.checkArgument(!Objects.isNull(req.getSubjectType()), "题目类型不能为空!");
PracticeSubjectDTO dto = new PracticeSubjectDTO();
dto.setSubjectId(req.getSubjectId());
dto.setSubjectType(req.getSubjectType());
PracticeSubjectVO vo = practiceSetService.getPracticeSubject(dto);
if (log.isInfoEnabled()) {
log.info("获取练习题目详情出参{}", JSON.toJSONString(vo));
}
return Result.ok(vo);
} catch (IllegalArgumentException e) {
log.error("参数异常!错误原因{}", e.getMessage(), e);
return Result.fail(e.getMessage());
} catch (Exception e) {
log.error("获取练习详情异常!错误原因{}", e.getMessage(), e);
return Result.fail("获取练习题目详情异常!");
}
}
/**
* 获取模拟套题内容
*/
@PostMapping(value = "/getPreSetContent")
public Result<PageResult<PracticeSetVO>> getPreSetContent(@RequestBody GetPreSetReq req) {
if (log.isInfoEnabled()) {
log.info("获取模拟套题内容入参{}", JSON.toJSONString(req));
}
try {
Preconditions.checkArgument(!Objects.isNull(req), "参数不能为空!");
PracticeSetDTO dto = new PracticeSetDTO();
dto.setOrderType(req.getOrderType());
dto.setPageInfo(req.getPageInfo());
dto.setSetName(req.getSetName());
PageResult<PracticeSetVO> list = practiceSetService.getPreSetContent(dto);
if (log.isInfoEnabled()) {
log.info("获取模拟套题内容出参{}", JSON.toJSONString(list));
}
return Result.ok(list);
} catch (IllegalArgumentException e) {
log.error("参数异常!错误原因{}", e.getMessage(), e);
return Result.fail(e.getMessage());
} catch (Exception e) {
log.error("获取模拟套题内容异常!错误原因{}", e.getMessage(), e);
return Result.fail("获取模拟套题内容异常!");
}
}
/**
* 获取未完成的练题内容
*/
@PostMapping(value = "/getUnCompletePractice")
public Result<PageResult<UnCompletePracticeSetVO>> getUnCompletePractice(@RequestBody GetUnCompletePracticeReq req) {
try {
Preconditions.checkArgument(!Objects.isNull(req), "参数不能为空!");
PageResult<UnCompletePracticeSetVO> list = practiceSetService.getUnCompletePractice(req);
if (log.isInfoEnabled()) {
log.info("获取未完成练习内容出参{}", JSON.toJSONString(list));
}
return Result.ok(list);
} catch (IllegalArgumentException e) {
log.error("参数异常!错误原因{}", e.getMessage(), e);
return Result.fail(e.getMessage());
} catch (Exception e) {
log.error("获取未完成练习内容异常!错误原因{}", e.getMessage(), e);
return Result.fail("获取未完成练习内容异常!");
}
}
}

View File

@@ -0,0 +1,43 @@
package com.landaiqing.practice.server.dao;
import com.landaiqing.practice.server.entity.po.PracticePO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface PracticeDao {
/**
* 根据练题id获取详情
*/
PracticePO selectById(Long id);
/**
* 新增
*/
int insert(PracticePO practicePO);
/**
* 更新练习详情
*/
int update(PracticePO practicePO);
/**
* 删除练习
*/
int deleteById(Long id);
/**
* 查询未完成的练习题数量
*/
Integer getUnCompleteCount(String loginId);
/**
* 查询未完成的练习题
*/
List<PracticePO> getUnCompleteList(@Param("loginId") String loginId,
@Param("limit") int limit,
@Param("offset") int pageSize);
}

View File

@@ -0,0 +1,53 @@
package com.landaiqing.practice.server.dao;
import com.landaiqing.practice.server.entity.po.PracticeDetailPO;
import com.landaiqing.practice.server.entity.po.PracticeRankPO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface PracticeDetailDao {
/**
* 获取正确答案数量
*/
int selectCorrectCount(Long practiceId);
/**
* 获取得分情况
*/
List<PracticeDetailPO> selectByPracticeId(Long practiceId);
/**
* 插入练题记录
*/
int insertSingle(PracticeDetailPO practiceDetailPO);
/**
* 根据练习id题目id查询详情
*/
PracticeDetailPO selectDetail(@Param("practiceId") Long practiceId,
@Param("subjectId") Long subjectId,
@Param("loginId") String loginId);
/**
* 更新练习详情
*/
int update(PracticeDetailPO practiceDetailPO);
/**
* 获取答案情况
*/
PracticeDetailPO selectAnswer(@Param("practiceId") Long practiceId,@Param("subjectId") Long subjectId);
/**
* 获取排行榜情况
*/
List<PracticeRankPO> getPracticeCount();
/**
* 删除练习详情
*/
int deleteByPracticeId(Long practiceId);
}

View File

@@ -0,0 +1,32 @@
package com.landaiqing.practice.server.dao;
import com.landaiqing.practice.server.entity.dto.PracticeSetDTO;
import com.landaiqing.practice.server.entity.po.PracticeSetPO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface PracticeSetDao {
/**
* 新增套题
*/
int add(PracticeSetPO po);
PracticeSetPO selectById(Long setId);
int updateHeat(Long setId);
/**
* 获取模拟考卷列表数量
*/
Integer getListCount(PracticeSetDTO dto);
/**
* 获取模拟考卷列表
*/
List<PracticeSetPO> getSetList(@Param("dto") PracticeSetDTO dto,
@Param("limit") int limit,
@Param("offset") int offset);
}

View File

@@ -0,0 +1,17 @@
package com.landaiqing.practice.server.dao;
import com.landaiqing.practice.server.entity.po.PracticeSetDetailPO;
import java.util.List;
public interface PracticeSetDetailDao {
/**
* 新增套题
*/
int add(PracticeSetDetailPO po);
List<PracticeSetDetailPO> selectBySetId(Long setId);
}

View File

@@ -0,0 +1,25 @@
package com.landaiqing.practice.server.dao;
import com.landaiqing.practice.server.entity.dto.CategoryDTO;
import com.landaiqing.practice.server.entity.po.CategoryPO;
import com.landaiqing.practice.server.entity.po.PrimaryCategoryPO;
import java.util.List;
/**
* 题目分类(SubjectCategory)表数据库访问层
*
* @author makejava
* @since 2023-10-01 21:49:58
*/
public interface SubjectCategoryDao {
List<PrimaryCategoryPO> getPrimaryCategory(CategoryDTO categoryDTO);
CategoryPO selectById(Long id);
List<CategoryPO> selectList(CategoryDTO categoryDTOTemp);
}

View File

@@ -0,0 +1,19 @@
package com.landaiqing.practice.server.dao;
import com.landaiqing.practice.server.entity.dto.PracticeSubjectDTO;
import com.landaiqing.practice.server.entity.po.SubjectPO;
import java.util.List;
public interface SubjectDao {
/**
* 获取练习面试题目
*/
List<SubjectPO> getPracticeSubject(PracticeSubjectDTO dto);
SubjectPO selectById(Long subjectId);
}

View File

@@ -0,0 +1,11 @@
package com.landaiqing.practice.server.dao;
import com.landaiqing.practice.server.entity.po.SubjectJudgePO;
public interface SubjectJudgeDao {
SubjectJudgePO selectBySubjectId(Long repeatSubjectId);
}

View File

@@ -0,0 +1,31 @@
package com.landaiqing.practice.server.dao;
import com.landaiqing.practice.server.entity.po.SubjectLabelPO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 题目标签表(SubjectLabel)表数据库访问层
*
* @author makejava
* @since 2023-10-03 21:50:29
*/
public interface SubjectLabelDao {
/**
* 通过ID查询单条数据
*
* @param id 主键
* @return 实例对象
*/
SubjectLabelPO queryById(Long id);
/**
* 批量查询当前题目的标签名称
*/
List<String> getLabelNameByIds(@Param("labelIds") List<Long> labelIds);
}

View File

@@ -0,0 +1,24 @@
package com.landaiqing.practice.server.dao;
import com.landaiqing.practice.server.entity.po.LabelCountPO;
import com.landaiqing.practice.server.entity.po.SubjectMappingPO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 题目分类关系表(SubjectMapping)表数据库访问层
*
* @author makejava
* @since 2023-10-03 22:17:07
*/
public interface SubjectMappingDao {
List<LabelCountPO> getLabelSubjectCount(@Param("categoryId") Long categoryId,
@Param("subjectTypeList") List<Integer> subjectTypeList);
List<SubjectMappingPO> getLabelIdsBySubjectId(Long subjectId);
}

View File

@@ -0,0 +1,14 @@
package com.landaiqing.practice.server.dao;
import com.landaiqing.practice.server.entity.po.SubjectMultiplePO;
import java.util.List;
public interface SubjectMultipleDao {
/**
* 查询题目
*/
List<SubjectMultiplePO> selectBySubjectId(Long subjectId);
}

View File

@@ -0,0 +1,14 @@
package com.landaiqing.practice.server.dao;
import com.landaiqing.practice.server.entity.po.SubjectRadioPO;
import java.util.List;
public interface SubjectRadioDao {
/**
* 根据题目id查询单选题目
*/
List<SubjectRadioPO> selectBySubjectId(Long subjectId);
}

View File

@@ -0,0 +1,23 @@
package com.landaiqing.practice.server.entity.dto;
import lombok.Data;
import java.util.List;
/**
* @Classname CategoryDTO
* @BelongsProject: qing-yu-club
* @BelongsPackage: com.landaiqing.practice.server.entity.dto
* @Author: landaiqing
* @CreateTime: 2024-03-12 17:45
* @Description: TODO
* @Version: 1.0
*/
@Data
public class CategoryDTO {
private List<Integer> subjectTypeList;
private Integer categoryType;
private Long parentId;
}

View File

@@ -0,0 +1,49 @@
package com.landaiqing.practice.server.entity.dto;
import com.landaiqing.practice.api.common.PageInfo;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class PracticeSetDTO implements Serializable {
/**
* 排除的套题id
*/
private List<Long> excludeSetId;
/**
* 套题类型
*/
private Integer setType;
/**
* 大类id
*/
private Long primaryCategoryId;
/**
* 数量
*/
private Integer limitCount;
/**
* 排序类型 1默认 2最新 3最热
*/
private Integer orderType;
/**
* 套题名称
*/
private String setName;
/**
* 分页信息
*/
private PageInfo pageInfo;
}

View File

@@ -0,0 +1,35 @@
package com.landaiqing.practice.server.entity.dto;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class PracticeSubjectDTO implements Serializable {
/**
* 分类与标签组合的ids
*/
private List<String> assembleIds;
/**
* 题目类型
*/
private Integer subjectType;
/**
* 题目数量
*/
private Integer subjectCount;
/**
* 要排除的题目id
*/
private List<Long> excludeSubjectIds;
/**
* 题目类型
*/
private Long subjectId;
}

View File

@@ -0,0 +1,30 @@
package com.landaiqing.practice.server.entity.dto;
import lombok.Data;
import java.io.Serializable;
@Data
public class SubjectDTO implements Serializable {
/**
* 题目id
*/
private Long id;
/**
* 题目id
*/
private Long subjectId;
/**
* 题目名称
*/
private String subjectName;
/**
* 题目类型
*/
private Integer subjectType;
}

View File

@@ -0,0 +1,37 @@
package com.landaiqing.practice.server.entity.dto;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class SubjectDetailDTO implements Serializable {
/**
* 题目id
*/
private Long id;
/**
* 题目名称
*/
private String subjectName;
/**
* 判断题答案
*/
private Integer isCorrect;
/**
* 题目解析
*/
private String subjectParse;
/**
* 单选、多选、判断题目答案
*/
private List<SubjectOptionDTO> optionList;
}

View File

@@ -0,0 +1,25 @@
package com.landaiqing.practice.server.entity.dto;
import lombok.Data;
import java.io.Serializable;
@Data
public class SubjectOptionDTO implements Serializable {
/**
* 答案类型
*/
private Integer optionType;
/**
* 答案内容
*/
private String optionContent;
/**
* 是否为正确答案
*/
private Integer isCorrect;
}

View File

@@ -0,0 +1,14 @@
package com.landaiqing.practice.server.entity.dto;
import lombok.Data;
@Data
public class UserInfo {
private String userName;
private String nickName;
private String avatar;
}

View File

@@ -0,0 +1,22 @@
package com.landaiqing.practice.server.entity.po;
import lombok.Data;
/**
* @Classname PrimaryCategoryPO
* @BelongsProject: qing-yu-club
* @BelongsPackage: com.landaiqing.practice.server.entity.po
* @Author: landaiqing
* @CreateTime: 2024-03-12 17:52
* @Description: TODO
* @Version: 1.0
*/
@Data
public class CategoryPO {
private Long id;
private String categoryName;
private Integer categoryType;
private Long parentId;
}

View File

@@ -0,0 +1,21 @@
package com.landaiqing.practice.server.entity.po;
import lombok.Data;
/**
* @Classname PrimaryCategoryPO
* @BelongsProject: qing-yu-club
* @BelongsPackage: com.landaiqing.practice.server.entity.po
* @Author: landaiqing
* @CreateTime: 2024-03-12 17:52
* @Description: TODO
* @Version: 1.0
*/
@Data
public class LabelCountPO {
private Long labelId;
private Integer count;
private String labelName;
}

View File

@@ -0,0 +1,63 @@
package com.landaiqing.practice.server.entity.po;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
@Data
public class PracticeDetailPO implements Serializable {
/**
* 主键
*/
private Long id;
/**
* 练题id
*/
private Long practiceId;
/**
* 题目id
*/
private Long subjectId;
/**
* 题目类型
*/
private Integer subjectType;
/**
* 是否正确 1正确 0错误
*/
private Integer answerStatus;
/**
* 答案内容
*/
private String answerContent;
/**
* 创建人
*/
private String createdBy;
/**
* 创建时间
*/
private Date createdTime;
/**
* 更新人
*/
private String updateBy;
private Integer isDeleted;
/**
* 更新时间
*/
private Date updateTime;
}

View File

@@ -0,0 +1,64 @@
package com.landaiqing.practice.server.entity.po;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
@Data
public class PracticePO implements Serializable {
/**
* 主键
*/
private Long id;
/**
* 套题id
*/
private Long setId;
/**
* 完成情况 1完成 0未完成
*/
private Integer completeStatus;
/**
* 所用时间
*/
private String timeUse;
/**
* 交卷时间
*/
private Date submitTime;
/**
* 正确率
*/
private BigDecimal correctRate;
/**
* 创建人
*/
private String createdBy;
/**
* 创建时间
*/
private Date createdTime;
/**
* 更新人
*/
private String updateBy;
private Integer isDeleted;
/**
* 更新时间
*/
private Date updateTime;
}

View File

@@ -0,0 +1,20 @@
package com.landaiqing.practice.server.entity.po;
import lombok.Data;
import java.io.Serializable;
@Data
public class PracticeRankPO implements Serializable {
/**
* 练习数量
*/
private Integer count;
/**
* 创建人
*/
private String createdBy;
}

View File

@@ -0,0 +1,50 @@
package com.landaiqing.practice.server.entity.po;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
@Data
public class PracticeSetDetailPO implements Serializable {
/**
* 主键
*/
private Long id;
/**
* 套题id
*/
private Long setId;
/**
* 题目id
*/
private Long subjectId;
/**
* 题目类型
*/
private Integer subjectType;
/**
* 创建人
*/
private String createdBy;
/**
* 创建时间
*/
private Date createdTime;
/**
* 更新人
*/
private String updateBy;
private Integer isDeleted;
/**
* 更新时间
*/
private Date updateTime;
}

View File

@@ -0,0 +1,60 @@
package com.landaiqing.practice.server.entity.po;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
@Data
public class PracticeSetPO implements Serializable {
/**
* 主键
*/
private Long id;
/**
* 套题名称
*/
private String setName;
/**
* 1实时生成 2预设套题
*/
private Integer setType;
/**
* 套题热度
*/
private Integer setHeat;
/**
* 套题描述
*/
private String setDesc;
/**
* 大类id
*/
private Long primaryCategoryId;
/**
* 创建人
*/
private String createdBy;
/**
* 创建时间
*/
private Date createdTime;
/**
* 更新人
*/
private String updateBy;
private Integer isDeleted;
/**
* 更新时间
*/
private Date updateTime;
}

View File

@@ -0,0 +1,22 @@
package com.landaiqing.practice.server.entity.po;
import lombok.Data;
/**
* @Classname PrimaryCategoryPO
* @BelongsProject: qing-yu-club
* @BelongsPackage: com.landaiqing.practice.server.entity.po
* @Author: landaiqing
* @CreateTime: 2024-03-12 17:52
* @Description: TODO
* @Version: 1.0
*/
@Data
public class PrimaryCategoryPO {
private Long id;
private String categoryName;
private Integer categoryType;
private Long parentId;
}

View File

@@ -0,0 +1,42 @@
package com.landaiqing.practice.server.entity.po;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
@Data
public class SubjectJudgePO implements Serializable {
private static final long serialVersionUID = 725783721496341698L;
/**
* 主键
*/
private Long id;
/**
* 题目id
*/
private Long subjectId;
/**
* 是否正确
*/
private Integer isCorrect;
/**
* 创建人
*/
private String createdBy;
/**
* 创建时间
*/
private Date createdTime;
/**
* 更新人
*/
private String updateBy;
/**
* 更新时间
*/
private Date updateTime;
private Integer isDeleted;
}

View File

@@ -0,0 +1,51 @@
package com.landaiqing.practice.server.entity.po;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* 题目标签表(SubjectLabel)实体类
*
* @author landaiqing
* @since 2024-02-14 17:08:06
*/
@Data
public class SubjectLabelPO implements Serializable {
/**
* 主键
*/
private Long id;
/**
* 标签分类
*/
private String labelName;
/**
* 排序
*/
private Integer sortNum;
private Long categoryId;
/**
* 创建人
*/
private String createdBy;
/**
* 创建时间
*/
private Date createdTime;
/**
* 更新人
*/
private String updateBy;
/**
* 更新时间
*/
private Date updateTime;
private Integer isDeleted;
}

View File

@@ -0,0 +1,47 @@
package com.landaiqing.practice.server.entity.po;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
@Data
public class SubjectMappingPO implements Serializable {
/**
* 主键
*/
private Long id;
/**
* 题目id
*/
private Long subjectId;
/**
* 分类id
*/
private Long categoryId;
/**
* 标签id
*/
private Long labelId;
/**
* 创建人
*/
private String createdBy;
/**
* 创建时间
*/
private Date createdTime;
/**
* 修改人
*/
private String updateBy;
/**
* 修改时间
*/
private Date updateTime;
private Integer isDeleted;
}

View File

@@ -0,0 +1,50 @@
package com.landaiqing.practice.server.entity.po;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
@Data
public class SubjectMultiplePO implements Serializable {
private static final long serialVersionUID = 575755837160743772L;
/**
* 主键
*/
private Long id;
/**
* 题目id
*/
private Long subjectId;
/**
* 选项类型
*/
private Integer optionType;
/**
* 选项内容
*/
private String optionContent;
/**
* 是否正确
*/
private Integer isCorrect;
/**
* 创建人
*/
private String createdBy;
/**
* 创建时间
*/
private Date createdTime;
/**
* 更新人
*/
private String updateBy;
private Integer isDeleted;
/**
* 更新时间
*/
private Date updateTime;
}

View File

@@ -0,0 +1,65 @@
package com.landaiqing.practice.server.entity.po;
import lombok.Data;
import java.io.Serializable;
@Data
public class SubjectPO implements Serializable {
/**
* 题目id/主键
*/
private Long id;
/**
* es的文档id
*/
private Long docId;
/**
* 题目名称
*/
private String subjectName;
/**
* 题目答案
*/
private String subjectAnswer;
/**
* 题目难度 DifficultyTypeEnum
*/
private Integer difficulty;
/**
* 出题人erp
*/
private String setterErp;
/**
* 出题人姓名
*/
private String setterName;
/**
* 是否推送
*/
private Integer isPush;
/**
* 题目类型
*/
private Integer subjectType;
/**
* 题目分数
*/
private Integer subjectScore;
/**
* 题目解析
*/
private String subjectParse;
}

View File

@@ -0,0 +1,50 @@
package com.landaiqing.practice.server.entity.po;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
@Data
public class SubjectRadioPO implements Serializable {
/**
* 主键
*/
private Long id;
/**
* 题目id
*/
private Long subjectId;
/**
* a,b,c,d
*/
private Integer optionType;
/**
* 选项内容
*/
private String optionContent;
/**
* 是否正确
*/
private Integer isCorrect;
/**
* 创建人
*/
private String createdBy;
/**
* 创建时间
*/
private Date createdTime;
/**
* 更新人
*/
private String updateBy;
private Integer isDeleted;
/**
* 更新时间
*/
private Date updateTime;
}

View File

@@ -0,0 +1,32 @@
package com.landaiqing.practice.server.rpc;
import com.landaiqing.auth.api.UserFeignService;
import com.landaiqing.auth.entity.AuthUserDTO;
import com.landaiqing.auth.entity.Result;
import com.landaiqing.practice.server.entity.dto.UserInfo;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Component
public class UserRpc {
@Resource
private UserFeignService userFeignService;
public UserInfo getUserInfo(String userName) {
AuthUserDTO authUserDTO = new AuthUserDTO();
authUserDTO.setUserName(userName);
Result<AuthUserDTO> result = userFeignService.getUserInfo(authUserDTO);
UserInfo userInfo = new UserInfo();
if (!result.getSuccess()) {
return userInfo;
}
AuthUserDTO data = result.getData();
userInfo.setUserName(data.getUserName());
userInfo.setNickName(data.getNickName());
userInfo.setAvatar(data.getAvatar());
return userInfo;
}
}

View File

@@ -0,0 +1,48 @@
package com.landaiqing.practice.server.service;
import com.landaiqing.practice.api.req.*;
import com.landaiqing.practice.api.vo.RankVO;
import com.landaiqing.practice.api.vo.ReportVO;
import com.landaiqing.practice.api.vo.ScoreDetailVO;
import com.landaiqing.practice.api.vo.SubjectDetailVO;
import java.util.List;
public interface PracticeDetailService {
/**
* 练习提交题目
*/
Boolean submitSubject(SubmitSubjectDetailReq req);
/**
* 提交练题情况
*/
Boolean submit(SubmitPracticeDetailReq req);
/**
* 每题得分详情
*/
List<ScoreDetailVO> getScoreDetail(GetScoreDetailReq req);
/**
* 获得答案详情
*/
SubjectDetailVO getSubjectDetail(GetSubjectDetailReq req);
/**
* 答案解析-评估报告
*/
ReportVO getReport(GetReportReq req);
/**
* 练习榜
*/
List<RankVO> getPracticeRankList();
/**
* 放弃练习
*/
Boolean giveUp(Long practiceId);
}

View File

@@ -0,0 +1,43 @@
package com.landaiqing.practice.server.service;
import com.landaiqing.practice.api.common.PageResult;
import com.landaiqing.practice.api.req.GetPracticeSubjectsReq;
import com.landaiqing.practice.api.req.GetUnCompletePracticeReq;
import com.landaiqing.practice.api.vo.*;
import com.landaiqing.practice.server.entity.dto.PracticeSetDTO;
import com.landaiqing.practice.server.entity.dto.PracticeSubjectDTO;
import java.util.List;
public interface PracticeSetService {
/**
* 获取专项练习内容
*/
List<SpecialPracticeVO> getSpecialPracticeContent();
/**
* 开始练习
*/
PracticeSetVO addPractice(PracticeSubjectDTO dto);
/**
* 获取练习题
*/
PracticeSubjectListVO getSubjects(GetPracticeSubjectsReq req);
/**
* 获取题目
*/
PracticeSubjectVO getPracticeSubject(PracticeSubjectDTO dto);
/**
* 获取模拟套题内容
*/
PageResult<PracticeSetVO> getPreSetContent(PracticeSetDTO dto);
/**
* 获取未完成练习内容
*/
PageResult<UnCompletePracticeSetVO> getUnCompletePractice(GetUnCompletePracticeReq req);
}

View File

@@ -0,0 +1,400 @@
package com.landaiqing.practice.server.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.landaiqing.practice.api.enums.*;
import com.landaiqing.practice.api.req.*;
import com.landaiqing.practice.api.vo.*;
import com.landaiqing.practice.server.dao.*;
import com.landaiqing.practice.server.entity.dto.*;
import com.landaiqing.practice.server.entity.po.*;
import com.landaiqing.practice.server.rpc.UserRpc;
import com.landaiqing.practice.server.service.PracticeDetailService;
import com.landaiqing.practice.server.util.DateUtils;
import com.landaiqing.practice.server.util.LoginUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
@Service
@Slf4j
public class PracticeDetailServiceImpl implements PracticeDetailService {
@Resource
private PracticeDetailDao practiceDetailDao;
@Resource
private PracticeSetDao practiceSetDao;
@Resource
private PracticeSetDetailDao practiceSetDetailDao;
@Resource
private PracticeDao practiceDao;
@Resource
private SubjectDao subjectDao;
@Resource
private SubjectRadioDao subjectRadioDao;
@Resource
private SubjectMultipleDao subjectMultipleDao;
@Resource
private SubjectJudgeDao subjectJudgeDao;
@Resource
private SubjectMappingDao subjectMappingDao;
@Resource
private SubjectLabelDao subjectLabelDao;
@Resource
private UserRpc userRpc;
@Override
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
public Boolean submit(SubmitPracticeDetailReq req) {
PracticePO practicePO = new PracticePO();
Long practiceId = req.getPracticeId();
Long setId = req.getSetId();
practicePO.setSetId(setId);
String timeUse = req.getTimeUse();
String hour = timeUse.substring(0, 2);
String minute = timeUse.substring(2, 4);
String second = timeUse.substring(4, 6);
practicePO.setTimeUse(hour + ":" + minute + ":" + second);
practicePO.setSubmitTime(DateUtils.parseStrToDate(req.getSubmitTime()));
practicePO.setCompleteStatus(CompleteStatusEnum.COMPLETE.getCode());
practicePO.setIsDeleted(IsDeletedFlagEnum.UN_DELETED.getCode());
practicePO.setCreatedBy(LoginUtil.getLoginId());
practicePO.setCreatedTime(new Date());
//计算正确率
Integer correctCount = practiceDetailDao.selectCorrectCount(practiceId);
List<PracticeSetDetailPO> practiceSetDetailPOS = practiceSetDetailDao.selectBySetId(setId);
Integer totalCount = practiceSetDetailPOS.size();
BigDecimal correctRate = new BigDecimal(correctCount).divide(new BigDecimal(totalCount), 4, BigDecimal.ROUND_HALF_UP)
.multiply(new BigDecimal("100.00"));
practicePO.setCorrectRate(correctRate);
PracticePO po = practiceDao.selectById(practiceId);
if (Objects.isNull(po)) {
practiceDao.insert(practicePO);
} else {
practicePO.setId(practiceId);
practiceDao.update(practicePO);
}
practiceSetDao.updateHeat(setId);
//补充剩余题目的记录
List<PracticeDetailPO> practiceDetailPOList = practiceDetailDao.selectByPracticeId(practiceId);
List<PracticeSetDetailPO> minusList = practiceSetDetailPOS.stream()
.filter(item -> !practiceDetailPOList.stream()
.map(e -> e.getSubjectId())
.collect(Collectors.toList())
.contains(item.getSubjectId()))
.collect(Collectors.toList());
if (log.isInfoEnabled()) {
log.info("题目差集{}", JSON.toJSONString(minusList));
}
if (CollectionUtils.isNotEmpty(minusList)) {
minusList.forEach(e -> {
PracticeDetailPO practiceDetailPO = new PracticeDetailPO();
practiceDetailPO.setPracticeId(practiceId);
practiceDetailPO.setSubjectType(e.getSubjectType());
practiceDetailPO.setSubjectId(e.getSubjectId());
practiceDetailPO.setAnswerStatus(0);
practiceDetailPO.setAnswerContent("");
practiceDetailPO.setIsDeleted(IsDeletedFlagEnum.UN_DELETED.getCode());
practiceDetailPO.setCreatedTime(new Date());
practiceDetailPO.setCreatedBy(LoginUtil.getLoginId());
practiceDetailDao.insertSingle(practiceDetailPO);
});
}
return true;
}
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean submitSubject(SubmitSubjectDetailReq req) {
String timeUse = req.getTimeUse();
if (timeUse.equals("0")) {
timeUse = "000000";
}
String hour = timeUse.substring(0, 2);
String minute = timeUse.substring(2, 4);
String second = timeUse.substring(4, 6);
PracticePO practicePO = new PracticePO();
practicePO.setId(req.getPracticeId());
practicePO.setTimeUse(hour + ":" + minute + ":" + second);
practicePO.setSubmitTime(new Date());
practiceDao.update(practicePO);
PracticeDetailPO practiceDetailPO = new PracticeDetailPO();
practiceDetailPO.setPracticeId(req.getPracticeId());
practiceDetailPO.setSubjectId(req.getSubjectId());
practiceDetailPO.setSubjectType(req.getSubjectType());
String answerContent = "";
//排序答案
if (CollectionUtils.isNotEmpty(req.getAnswerContents())) {
List<Integer> answerContents = req.getAnswerContents();
Collections.sort(answerContents);
answerContent = StringUtils.join(answerContents, ",");
}
practiceDetailPO.setAnswerContent(answerContent);
SubjectDTO subjectDTO = new SubjectDTO();
subjectDTO.setSubjectId(req.getSubjectId());
subjectDTO.setSubjectType(req.getSubjectType());
//获取正确答案,并判断答案是否正确
SubjectDetailDTO subjectDetail = getSubjectDetail(subjectDTO);
StringBuffer correctAnswer = new StringBuffer();
if (req.getSubjectType().equals(SubjectInfoTypeEnum.JUDGE.getCode())) {
Integer isCorrect = subjectDetail.getIsCorrect();
correctAnswer.append(isCorrect);
} else {
subjectDetail.getOptionList().forEach(e -> {
if (Objects.equals(e.getIsCorrect(), 1)) {
correctAnswer.append(e.getOptionType()).append(",");
}
});
if (correctAnswer.length() > 0) {
correctAnswer.deleteCharAt(correctAnswer.length() - 1);
}
}
if (Objects.equals(correctAnswer.toString(), answerContent)) {
practiceDetailPO.setAnswerStatus(1);
} else {
practiceDetailPO.setAnswerStatus(0);
}
practiceDetailPO.setIsDeleted(IsDeletedFlagEnum.UN_DELETED.getCode());
practiceDetailPO.setCreatedBy(LoginUtil.getLoginId());
practiceDetailPO.setCreatedTime(new Date());
PracticeDetailPO existDetail = practiceDetailDao.selectDetail(req.getPracticeId(), req.getSubjectId(), LoginUtil.getLoginId());
if (Objects.isNull(existDetail)) {
practiceDetailDao.insertSingle(practiceDetailPO);
} else {
practiceDetailPO.setId(existDetail.getId());
practiceDetailDao.update(practiceDetailPO);
}
return true;
}
public SubjectDetailDTO getSubjectDetail(SubjectDTO dto) {
SubjectDetailDTO subjectDetailDTO = new SubjectDetailDTO();
SubjectPO subjectPO = subjectDao.selectById(dto.getSubjectId());
if (dto.getSubjectType() == SubjectInfoTypeEnum.RADIO.getCode()) {
List<SubjectOptionDTO> optionList = new LinkedList<>();
List<SubjectRadioPO> radioSubjectPOS = subjectRadioDao.selectBySubjectId(subjectPO.getId());
radioSubjectPOS.forEach(e -> {
SubjectOptionDTO subjectOptionDTO = new SubjectOptionDTO();
subjectOptionDTO.setOptionContent(e.getOptionContent());
subjectOptionDTO.setOptionType(e.getOptionType());
subjectOptionDTO.setIsCorrect(e.getIsCorrect());
optionList.add(subjectOptionDTO);
});
subjectDetailDTO.setOptionList(optionList);
}
if (dto.getSubjectType() == SubjectInfoTypeEnum.MULTIPLE.getCode()) {
List<SubjectOptionDTO> optionList = new LinkedList<>();
List<SubjectMultiplePO> multipleSubjectPOS = subjectMultipleDao.selectBySubjectId(subjectPO.getId());
multipleSubjectPOS.forEach(e -> {
SubjectOptionDTO subjectOptionDTO = new SubjectOptionDTO();
subjectOptionDTO.setOptionContent(e.getOptionContent());
subjectOptionDTO.setOptionType(e.getOptionType());
subjectOptionDTO.setIsCorrect(e.getIsCorrect());
optionList.add(subjectOptionDTO);
});
subjectDetailDTO.setOptionList(optionList);
}
if (dto.getSubjectType() == SubjectInfoTypeEnum.JUDGE.getCode()) {
SubjectJudgePO judgeSubjectPO = subjectJudgeDao.selectBySubjectId(subjectPO.getId());
subjectDetailDTO.setIsCorrect(judgeSubjectPO.getIsCorrect());
}
subjectDetailDTO.setSubjectParse(subjectPO.getSubjectParse());
subjectDetailDTO.setSubjectName(subjectPO.getSubjectName());
return subjectDetailDTO;
}
@Override
public List<ScoreDetailVO> getScoreDetail(GetScoreDetailReq req) {
Long practiceId = req.getPracticeId();
List<ScoreDetailVO> list = new LinkedList<>();
List<PracticeDetailPO> practiceDetailPOList = practiceDetailDao.selectByPracticeId(practiceId);
if (CollectionUtils.isEmpty(practiceDetailPOList)) {
return Collections.emptyList();
}
practiceDetailPOList.forEach(po -> {
ScoreDetailVO scoreDetailVO = new ScoreDetailVO();
scoreDetailVO.setSubjectId(po.getSubjectId());
scoreDetailVO.setSubjectType(po.getSubjectType());
scoreDetailVO.setIsCorrect(po.getAnswerStatus());
list.add(scoreDetailVO);
});
return list;
}
@Override
public SubjectDetailVO getSubjectDetail(GetSubjectDetailReq req) {
SubjectDetailVO subjectDetailVO = new SubjectDetailVO();
Long subjectId = req.getSubjectId();
Integer subjectType = req.getSubjectType();
SubjectDTO subjectDTO = new SubjectDTO();
subjectDTO.setSubjectId(subjectId);
subjectDTO.setSubjectType(subjectType);
SubjectDetailDTO subjectDetail = getSubjectDetail(subjectDTO);
List<SubjectOptionDTO> optionList = subjectDetail.getOptionList();
List<PracticeSubjectOptionVO> optionVOList = new LinkedList<>();
List<Integer> correctAnswer = new LinkedList<>();
if (CollectionUtils.isNotEmpty(optionList)) {
optionList.forEach(option -> {
PracticeSubjectOptionVO optionVO = new PracticeSubjectOptionVO();
optionVO.setOptionType(option.getOptionType());
optionVO.setOptionContent(option.getOptionContent());
optionVO.setIsCorrect(option.getIsCorrect());
optionVOList.add(optionVO);
if (option.getIsCorrect() == 1) {
correctAnswer.add(option.getOptionType());
}
});
}
if (subjectType.equals(SubjectInfoTypeEnum.JUDGE.getCode())) {
Integer isCorrect = subjectDetail.getIsCorrect();
PracticeSubjectOptionVO correctOption = new PracticeSubjectOptionVO();
correctOption.setOptionType(1);
correctOption.setOptionContent("正确");
correctOption.setIsCorrect(isCorrect == 1 ? 1 : 0);
PracticeSubjectOptionVO errorOptionVO = new PracticeSubjectOptionVO();
errorOptionVO.setOptionType(2);
errorOptionVO.setOptionContent("错误");
errorOptionVO.setIsCorrect(isCorrect == 0 ? 1 : 0);
optionVOList.add(correctOption);
optionVOList.add(errorOptionVO);
correctAnswer.add(subjectDetail.getIsCorrect());
}
subjectDetailVO.setOptionList(optionVOList);
subjectDetailVO.setSubjectParse(subjectDetail.getSubjectParse());
subjectDetailVO.setSubjectName(subjectDetail.getSubjectName());
subjectDetailVO.setCorrectAnswer(correctAnswer);
//自己的答题答案
List<Integer> respondAnswer = new LinkedList<>();
PracticeDetailPO practiceDetailPO = practiceDetailDao.selectAnswer(req.getPracticeId(), subjectId);
String answerContent = practiceDetailPO.getAnswerContent();
if (StringUtils.isNotBlank(answerContent)) {
String[] split = answerContent.split(",");
for (String s : split) {
respondAnswer.add(Integer.valueOf(s));
}
}
subjectDetailVO.setRespondAnswer(respondAnswer);
List<SubjectMappingPO> subjectMappingPOList = subjectMappingDao.getLabelIdsBySubjectId(subjectId);
List<Long> labelIdList = new LinkedList<>();
subjectMappingPOList.forEach(subjectMappingPO -> {
labelIdList.add(subjectMappingPO.getLabelId());
});
List<String> labelNameList = subjectLabelDao.getLabelNameByIds(labelIdList);
subjectDetailVO.setLabelNames(labelNameList);
return subjectDetailVO;
}
@Override
public ReportVO getReport(GetReportReq req) {
ReportVO reportVO = new ReportVO();
Long practiceId = req.getPracticeId();
PracticePO practicePO = practiceDao.selectById(practiceId);
Long setId = practicePO.getSetId();
PracticeSetPO practiceSetPO = practiceSetDao.selectById(setId);
reportVO.setTitle(practiceSetPO.getSetName());
List<PracticeDetailPO> practiceDetailPOList = practiceDetailDao.selectByPracticeId(practiceId);
if (CollectionUtils.isEmpty(practiceDetailPOList)) {
return null;
}
int totalCount = practiceDetailPOList.size();
List<PracticeDetailPO> correctPoList = practiceDetailPOList.stream().filter(e ->
Objects.equals(e.getAnswerStatus(), AnswerStatusEnum.CORRECT.getCode())).collect(Collectors.toList());
reportVO.setCorrectSubject(correctPoList.size() + "/" + totalCount);
List<ReportSkillVO> reportSkillVOS = new LinkedList<>();
Map<Long, Integer> totalMap = getSubjectLabelMap(practiceDetailPOList);
Map<Long, Integer> correctMap = getSubjectLabelMap(correctPoList);
totalMap.forEach((key, val) -> {
ReportSkillVO skillVO = new ReportSkillVO();
SubjectLabelPO labelPO = subjectLabelDao.queryById(key);
String labelName = labelPO.getLabelName();
Integer correctCount = correctMap.get(key);
if (Objects.isNull(correctCount)) {
correctCount = 0;
}
skillVO.setName(labelName);
BigDecimal rate = BigDecimal.ZERO;
if (!Objects.equals(val, 0)) {
rate = new BigDecimal(correctCount.toString()).divide(new BigDecimal(val.toString()), 4,
BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100));
}
skillVO.setStar(rate);
reportSkillVOS.add(skillVO);
});
if (log.isInfoEnabled()) {
log.info("获取到的正确率{}", JSON.toJSONString(reportSkillVOS));
}
reportVO.setSkill(reportSkillVOS);
return reportVO;
}
private Map<Long, Integer> getSubjectLabelMap(List<PracticeDetailPO> practiceDetailPOList) {
if (CollectionUtils.isEmpty(practiceDetailPOList)) {
return Collections.emptyMap();
}
Map<Long, Integer> map = new HashMap<>();
practiceDetailPOList.forEach(detail -> {
Long subjectId = detail.getSubjectId();
List<SubjectMappingPO> labelIdPO = subjectMappingDao.getLabelIdsBySubjectId(subjectId);
labelIdPO.forEach(po -> {
Long labelId = po.getLabelId();
if (Objects.isNull(map.get(labelId))) {
map.put(labelId, 1);
return;
}
map.put(labelId, map.get(labelId) + 1);
});
});
if (log.isInfoEnabled()) {
log.info("获取到的题目对应的标签map{}", JSON.toJSONString(map));
}
return map;
}
@Override
public List<RankVO> getPracticeRankList() {
List<RankVO> list = new LinkedList<>();
List<PracticeRankPO> poList = practiceDetailDao.getPracticeCount();
if (CollectionUtils.isEmpty(poList)) {
return list;
}
poList.forEach(e -> {
RankVO rankVO = new RankVO();
rankVO.setCount(e.getCount());
UserInfo userInfo = userRpc.getUserInfo(e.getCreatedBy());
rankVO.setName(userInfo.getNickName());
rankVO.setAvatar(userInfo.getAvatar());
list.add(rankVO);
});
return list;
}
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean giveUp(Long practiceId) {
practiceDetailDao.deleteByPracticeId(practiceId);
practiceDao.deleteById(practiceId);
return true;
}
}

View File

@@ -0,0 +1,394 @@
package com.landaiqing.practice.server.service.impl;
import com.alibaba.fastjson.JSON;
import com.landaiqing.practice.api.common.PageInfo;
import com.landaiqing.practice.api.common.PageResult;
import com.landaiqing.practice.api.enums.CompleteStatusEnum;
import com.landaiqing.practice.api.enums.IsDeletedFlagEnum;
import com.landaiqing.practice.api.enums.SubjectInfoTypeEnum;
import com.landaiqing.practice.api.req.GetPracticeSubjectsReq;
import com.landaiqing.practice.api.req.GetUnCompletePracticeReq;
import com.landaiqing.practice.api.vo.*;
import com.landaiqing.practice.server.dao.*;
import com.landaiqing.practice.server.entity.dto.CategoryDTO;
import com.landaiqing.practice.server.entity.dto.PracticeSetDTO;
import com.landaiqing.practice.server.entity.dto.PracticeSubjectDTO;
import com.landaiqing.practice.server.entity.po.*;
import com.landaiqing.practice.server.service.PracticeSetService;
import com.landaiqing.practice.server.util.DateUtils;
import com.landaiqing.practice.server.util.LoginUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
@Service
@Slf4j
public class PracticeSetServiceImpl implements PracticeSetService {
@Resource
private SubjectCategoryDao subjectCategoryDao;
@Resource
private SubjectMappingDao subjectMappingDao;
@Resource
private SubjectLabelDao subjectLabelDao;
@Resource
private PracticeSetDetailDao practiceSetDetailDao;
@Resource
private PracticeSetDao practiceSetDao;
@Resource
private SubjectDao subjectDao;
@Resource
private PracticeDetailDao practiceDetailDao;
@Resource
private PracticeDao practiceDao;
@Resource
private SubjectRadioDao subjectRadioDao;
@Resource
private SubjectMultipleDao subjectMultipleDao;
@Override
public List<SpecialPracticeVO> getSpecialPracticeContent() {
List<SpecialPracticeVO> specialPracticeVOList = new LinkedList<>();
List<Integer> subjectTypeList = new LinkedList<>();
subjectTypeList.add(SubjectInfoTypeEnum.RADIO.getCode());
subjectTypeList.add(SubjectInfoTypeEnum.MULTIPLE.getCode());
subjectTypeList.add(SubjectInfoTypeEnum.JUDGE.getCode());
CategoryDTO categoryDTO = new CategoryDTO();
categoryDTO.setSubjectTypeList(subjectTypeList);
List<PrimaryCategoryPO> poList = subjectCategoryDao.getPrimaryCategory(categoryDTO);
if (CollectionUtils.isEmpty(poList)) {
return specialPracticeVOList;
}
poList.forEach(primaryCategoryPO -> {
SpecialPracticeVO specialPracticeVO = new SpecialPracticeVO();
specialPracticeVO.setPrimaryCategoryId(primaryCategoryPO.getParentId());
CategoryPO categoryPO = subjectCategoryDao.selectById(primaryCategoryPO.getParentId());
specialPracticeVO.setPrimaryCategoryName(categoryPO.getCategoryName());
CategoryDTO categoryDTOTemp = new CategoryDTO();
categoryDTOTemp.setCategoryType(2);
categoryDTOTemp.setParentId(primaryCategoryPO.getParentId());
List<CategoryPO> smallPoList = subjectCategoryDao.selectList(categoryDTOTemp);
if (CollectionUtils.isEmpty(smallPoList)) {
return;
}
List<SpecialPracticeCategoryVO> categoryList = new LinkedList();
smallPoList.forEach(smallPo -> {
List<SpecialPracticeLabelVO> labelVOList = getLabelVOList(smallPo.getId(), subjectTypeList);
if (CollectionUtils.isEmpty(labelVOList)) {
return;
}
SpecialPracticeCategoryVO specialPracticeCategoryVO = new SpecialPracticeCategoryVO();
specialPracticeCategoryVO.setCategoryId(smallPo.getId());
specialPracticeCategoryVO.setCategoryName(smallPo.getCategoryName());
List<SpecialPracticeLabelVO> labelList = new LinkedList<>();
labelVOList.forEach(labelVo -> {
SpecialPracticeLabelVO specialPracticeLabelVO = new SpecialPracticeLabelVO();
specialPracticeLabelVO.setId(labelVo.getId());
specialPracticeLabelVO.setAssembleId(labelVo.getAssembleId());
specialPracticeLabelVO.setLabelName(labelVo.getLabelName());
labelList.add(specialPracticeLabelVO);
});
specialPracticeCategoryVO.setLabelList(labelList);
categoryList.add(specialPracticeCategoryVO);
});
specialPracticeVO.setCategoryList(categoryList);
specialPracticeVOList.add(specialPracticeVO);
});
return specialPracticeVOList;
}
@Override
@Transactional(rollbackFor = Exception.class)
public PracticeSetVO addPractice(PracticeSubjectDTO dto) {
PracticeSetVO setVO = new PracticeSetVO();
List<PracticeSubjectDetailVO> practiceList = getPracticeList(dto);
if (CollectionUtils.isEmpty(practiceList)) {
return setVO;
}
PracticeSetPO practiceSetPO = new PracticeSetPO();
practiceSetPO.setSetType(1);
List<String> assembleIds = dto.getAssembleIds();
Set<Long> categoryIdSet = new HashSet<>();
assembleIds.forEach(assembleId -> {
Long categoryId = Long.valueOf(assembleId.split("-")[0]);
categoryIdSet.add(categoryId);
});
StringBuffer setName = new StringBuffer();
int i = 1;
for (Long categoryId : categoryIdSet) {
if (i > 2) {
break;
}
CategoryPO categoryPO = subjectCategoryDao.selectById(categoryId);
setName.append(categoryPO.getCategoryName());
setName.append("");
i = i + 1;
}
setName.deleteCharAt(setName.length() - 1);
if (i == 2) {
setName.append("专项练习");
} else {
setName.append("等专项练习");
}
practiceSetPO.setSetName(setName.toString());
String labelId = assembleIds.get(0).split("-")[1];
SubjectLabelPO labelPO = subjectLabelDao.queryById(Long.valueOf(labelId));
practiceSetPO.setPrimaryCategoryId(labelPO.getCategoryId());
practiceSetPO.setIsDeleted(IsDeletedFlagEnum.UN_DELETED.getCode());
practiceSetPO.setCreatedBy(LoginUtil.getLoginId());
practiceSetPO.setCreatedTime(new Date());
practiceSetDao.add(practiceSetPO);
Long practiceSetId = practiceSetPO.getId();
//思考,这里哪里不符合规范,配合听视频的延伸
practiceList.forEach(e -> {
PracticeSetDetailPO detailPO = new PracticeSetDetailPO();
detailPO.setSetId(practiceSetId);
detailPO.setSubjectId(e.getSubjectId());
detailPO.setSubjectType(e.getSubjectType());
detailPO.setIsDeleted(IsDeletedFlagEnum.UN_DELETED.getCode());
detailPO.setCreatedBy(LoginUtil.getLoginId());
detailPO.setCreatedTime(new Date());
practiceSetDetailDao.add(detailPO);
});
setVO.setSetId(practiceSetId);
return setVO;
}
/**
* 获取套卷题目信息
*/
private List<PracticeSubjectDetailVO> getPracticeList(PracticeSubjectDTO dto) {
List<PracticeSubjectDetailVO> practiceSubjectListVOS = new LinkedList<>();
//避免重复
List<Long> excludeSubjectIds = new LinkedList<>();
//设置题目数量之后优化到nacos动态配置
Integer radioSubjectCount = 10;
Integer multipleSubjectCount = 6;
Integer judgeSubjectCount = 4;
Integer totalSubjectCount = 20;
//查询单选
dto.setSubjectCount(radioSubjectCount);
dto.setSubjectType(SubjectInfoTypeEnum.RADIO.getCode());
assembleList(dto, practiceSubjectListVOS, excludeSubjectIds);
//查询多选
dto.setSubjectCount(multipleSubjectCount);
dto.setSubjectType(SubjectInfoTypeEnum.MULTIPLE.getCode());
assembleList(dto, practiceSubjectListVOS, excludeSubjectIds);
//查询判断
dto.setSubjectCount(judgeSubjectCount);
dto.setSubjectType(SubjectInfoTypeEnum.JUDGE.getCode());
assembleList(dto, practiceSubjectListVOS, excludeSubjectIds);
//补充题目
if (practiceSubjectListVOS.size() == totalSubjectCount) {
return practiceSubjectListVOS;
}
Integer remainCount = totalSubjectCount - practiceSubjectListVOS.size();
dto.setSubjectCount(remainCount);
dto.setSubjectType(1);
assembleList(dto, practiceSubjectListVOS, excludeSubjectIds);
return practiceSubjectListVOS;
}
private List<PracticeSubjectDetailVO> assembleList(PracticeSubjectDTO dto, List<PracticeSubjectDetailVO> list, List<Long> excludeSubjectIds) {
dto.setExcludeSubjectIds(excludeSubjectIds);
List<SubjectPO> subjectPOList = subjectDao.getPracticeSubject(dto);
if (CollectionUtils.isEmpty(subjectPOList)) {
return list;
}
subjectPOList.forEach(e -> {
PracticeSubjectDetailVO vo = new PracticeSubjectDetailVO();
vo.setSubjectId(e.getId());
vo.setSubjectType(e.getSubjectType());
excludeSubjectIds.add(e.getId());
list.add(vo);
});
return list;
}
private List<SpecialPracticeLabelVO> getLabelVOList(Long categoryId, List<Integer> subjectTypeList) {
List<LabelCountPO> countPOList = subjectMappingDao.getLabelSubjectCount(categoryId, subjectTypeList);
if (CollectionUtils.isEmpty(countPOList)) {
return Collections.emptyList();
}
List<SpecialPracticeLabelVO> voList = new LinkedList<>();
countPOList.forEach(countPo -> {
SpecialPracticeLabelVO vo = new SpecialPracticeLabelVO();
vo.setId(countPo.getLabelId());
vo.setAssembleId(categoryId + "-" + countPo.getLabelId());
SubjectLabelPO subjectLabelPO = subjectLabelDao.queryById(countPo.getLabelId());
vo.setLabelName(subjectLabelPO.getLabelName());
voList.add(vo);
});
return voList;
}
@Override
public PracticeSubjectListVO getSubjects(GetPracticeSubjectsReq req) {
Long setId = req.getSetId();
PracticeSubjectListVO vo = new PracticeSubjectListVO();
List<PracticeSubjectDetailVO> practiceSubjectListVOS = new LinkedList<>();
List<PracticeSetDetailPO> practiceSetDetailPOS = practiceSetDetailDao.selectBySetId(setId);
if (CollectionUtils.isEmpty(practiceSetDetailPOS)) {
return vo;
}
String loginId = LoginUtil.getLoginId();
Long practiceId = req.getPracticeId();
practiceSetDetailPOS.forEach(e -> {
PracticeSubjectDetailVO practiceSubjectListVO = new PracticeSubjectDetailVO();
practiceSubjectListVO.setSubjectId(e.getSubjectId());
practiceSubjectListVO.setSubjectType(e.getSubjectType());
if (Objects.nonNull(practiceId)) {
PracticeDetailPO practiceDetailPO = practiceDetailDao.selectDetail(practiceId, e.getSubjectId(), loginId);
if (Objects.nonNull(practiceDetailPO) && StringUtils.isNotBlank(practiceDetailPO.getAnswerContent())) {
practiceSubjectListVO.setIsAnswer(1);
} else {
practiceSubjectListVO.setIsAnswer(0);
}
}
practiceSubjectListVOS.add(practiceSubjectListVO);
});
vo.setSubjectList(practiceSubjectListVOS);
PracticeSetPO practiceSetPO = practiceSetDao.selectById(setId);
vo.setTitle(practiceSetPO.getSetName());
if (Objects.isNull(practiceId)) {
Long newPracticeId = insertUnCompletePractice(setId);
vo.setPracticeId(newPracticeId);
} else {
updateUnCompletePractice(practiceId);
PracticePO practicePO = practiceDao.selectById(practiceId);
vo.setTimeUse(practicePO.getTimeUse());
vo.setPracticeId(practiceId);
}
return vo;
}
private Long insertUnCompletePractice(Long practiceSetId) {
PracticePO practicePO = new PracticePO();
practicePO.setSetId(practiceSetId);
practicePO.setCompleteStatus(CompleteStatusEnum.NO_COMPLETE.getCode());
practicePO.setTimeUse("00:00:00");
practicePO.setSubmitTime(new Date());
practicePO.setCorrectRate(new BigDecimal("0.00"));
practicePO.setIsDeleted(IsDeletedFlagEnum.UN_DELETED.getCode());
practicePO.setCreatedBy(LoginUtil.getLoginId());
practicePO.setCreatedTime(new Date());
practiceDao.insert(practicePO);
return practicePO.getId();
}
private void updateUnCompletePractice(Long practiceId) {
PracticePO practicePO = new PracticePO();
practicePO.setId(practiceId);
practicePO.setSubmitTime(new Date());
practiceDao.update(practicePO);
}
@Override
public PracticeSubjectVO getPracticeSubject(PracticeSubjectDTO dto) {
PracticeSubjectVO practiceSubjectVO = new PracticeSubjectVO();
SubjectPO subjectPO = subjectDao.selectById(dto.getSubjectId());
practiceSubjectVO.setSubjectName(subjectPO.getSubjectName());
practiceSubjectVO.setSubjectType(subjectPO.getSubjectType());
if (dto.getSubjectType() == SubjectInfoTypeEnum.RADIO.getCode()) {
List<PracticeSubjectOptionVO> optionList = new LinkedList<>();
List<SubjectRadioPO> radioSubjectPOS = subjectRadioDao.selectBySubjectId(subjectPO.getId());
radioSubjectPOS.forEach(e -> {
PracticeSubjectOptionVO practiceSubjectOptionVO = new PracticeSubjectOptionVO();
practiceSubjectOptionVO.setOptionContent(e.getOptionContent());
practiceSubjectOptionVO.setOptionType(e.getOptionType());
optionList.add(practiceSubjectOptionVO);
});
practiceSubjectVO.setOptionList(optionList);
}
if (dto.getSubjectType() == SubjectInfoTypeEnum.MULTIPLE.getCode()) {
List<PracticeSubjectOptionVO> optionList = new LinkedList<>();
List<SubjectMultiplePO> multipleSubjectPOS = subjectMultipleDao.selectBySubjectId(subjectPO.getId());
multipleSubjectPOS.forEach(e -> {
PracticeSubjectOptionVO practiceSubjectOptionVO = new PracticeSubjectOptionVO();
practiceSubjectOptionVO.setOptionContent(e.getOptionContent());
practiceSubjectOptionVO.setOptionType(e.getOptionType());
optionList.add(practiceSubjectOptionVO);
});
practiceSubjectVO.setOptionList(optionList);
}
return practiceSubjectVO;
}
@Override
public PageResult<PracticeSetVO> getPreSetContent(PracticeSetDTO dto) {
PageResult<PracticeSetVO> pageResult = new PageResult<>();
PageInfo pageInfo = dto.getPageInfo();
pageResult.setPageNo(pageInfo.getPageNo());
pageResult.setPageSize(pageInfo.getPageSize());
int start = (pageInfo.getPageNo() - 1) * pageInfo.getPageSize();
Integer count = practiceSetDao.getListCount(dto);
if (count == 0) {
return pageResult;
}
List<PracticeSetPO> setPOList = practiceSetDao.getSetList(dto, start, dto.getPageInfo().getPageSize());
if (log.isInfoEnabled()) {
log.info("获取的模拟考卷列表{}", JSON.toJSONString(setPOList));
}
List<PracticeSetVO> list = new LinkedList<>();
setPOList.forEach(e -> {
PracticeSetVO vo = new PracticeSetVO();
vo.setSetId(e.getId());
vo.setSetName(e.getSetName());
vo.setSetHeat(e.getSetHeat());
vo.setSetDesc(e.getSetDesc());
list.add(vo);
});
pageResult.setRecords(list);
pageResult.setTotal(count);
return pageResult;
}
@Override
public PageResult<UnCompletePracticeSetVO> getUnCompletePractice(GetUnCompletePracticeReq req) {
PageResult<UnCompletePracticeSetVO> pageResult = new PageResult<>();
PageInfo pageInfo = req.getPageInfo();
pageResult.setPageNo(pageInfo.getPageNo());
pageResult.setPageSize(pageInfo.getPageSize());
int start = (pageInfo.getPageNo() - 1) * pageInfo.getPageSize();
String loginId = LoginUtil.getLoginId();
Integer count = practiceDao.getUnCompleteCount(loginId);
if (count == 0) {
return pageResult;
}
List<PracticePO> poList = practiceDao.getUnCompleteList(loginId, start, req.getPageInfo().getPageSize());
if (log.isInfoEnabled()) {
log.info("获取未完成的考卷列表{}", JSON.toJSONString(poList));
}
List<UnCompletePracticeSetVO> list = new LinkedList<>();
poList.forEach(e -> {
UnCompletePracticeSetVO vo = new UnCompletePracticeSetVO();
vo.setSetId(e.getSetId());
vo.setPracticeId(e.getId());
vo.setPracticeTime(DateUtils.format(e.getSubmitTime(), "yyyy-MM-dd"));
PracticeSetPO practiceSetPO = practiceSetDao.selectById(e.getSetId());
vo.setTitle(practiceSetPO.getSetName());
list.add(vo);
});
pageResult.setRecords(list);
pageResult.setTotal(count);
return pageResult;
}
}

View File

@@ -0,0 +1,40 @@
package com.landaiqing.practice.server.util;
import lombok.extern.slf4j.Slf4j;
import java.text.SimpleDateFormat;
import java.util.Date;
@Slf4j
public class DateUtils {
/**
* 字符串转时间
*/
public static Date parseStrToDate(String timestamp) {
try {
SimpleDateFormat sm = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sm.parse(timestamp);
} catch (Exception e) {
log.error("parseDate异常{}", timestamp, e.getMessage(), e);
return null;
}
}
/**
* 日期格式化
*/
public static String format(Date date, String format) {
try {
if (date == null) {
return null;
}
SimpleDateFormat sdf = new SimpleDateFormat(format);
return sdf.format(date);
} catch (Exception e) {
log.error("日期格式化失败{}", e.getMessage(), e);
}
return null;
}
}

View File

@@ -0,0 +1,18 @@
package com.landaiqing.practice.server.util;
import com.landaiqing.practice.server.config.context.LoginContextHolder;
/**
* 用户登录util
*
* @author: ChickenWing
* @date: 2023/11/26
*/
public class LoginUtil {
public static String getLoginId() {
return LoginContextHolder.getLoginId();
}
}

View File

@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.landaiqing.practice.server.dao.PracticeDao">
<select id="selectById"
resultType="com.landaiqing.practice.server.entity.po.PracticePO">
select set_id as setId, time_use as timeUse, submit_time as submitTime, correct_rate as correctRate
from practice_info
where id = #{id,jdbcType=BIGINT}
and is_deleted = 0
</select>
<insert id="insert">
<selectKey resultType="java.lang.Long" keyProperty="id" order="AFTER">
SELECT LAST_INSERT_ID()
</selectKey>
INSERT INTO practice_info(set_id, complete_status,time_use,submit_time,correct_rate, is_deleted,
created_by, created_time)
values (#{setId,jdbcType=BIGINT},
#{completeStatus,jdbcType=INTEGER},
#{timeUse,jdbcType=VARCHAR},
#{submitTime,jdbcType=TIMESTAMP},
#{correctRate,jdbcType=VARCHAR},
#{isDeleted,jdbcType=INTEGER},
#{createdBy,jdbcType=VARCHAR},
#{createdTime,jdbcType=TIMESTAMP})
</insert>
<update id="update">
update practice_info
<set>
<if test="submitTime != null">
submit_time = #{submitTime},
</if>
<if test="timeUse != null">
time_use = #{timeUse},
</if>
<if test="completeStatus != null">
complete_status = #{completeStatus},
</if>
<if test="correctRate != null">
correct_rate = #{correctRate},
</if>
</set>
where id = #{id,jdbcType=BIGINT}
</update>
<update id="deleteById">
update practice_info
set is_deleted = 1
where id = #{id}
</update>
<select id="getUnCompleteCount" resultType="java.lang.Integer">
select count(1)
from practice_info
where created_by = #{loginId}
and complete_status = 0
and is_deleted = 0
</select>
<select id="getUnCompleteList"
resultType="com.landaiqing.practice.server.entity.po.PracticePO">
select id, set_id as setId, time_use as timeUse, submit_time as submitTime, correct_rate as correctRate
from practice_info
where created_by = #{loginId}
and is_deleted = 0
and complete_status = 0
order by submit_time desc
limit #{limit}, #{offset}
</select>
</mapper>

Some files were not shown because too many files have changed in this diff Show More