diff --git a/src/main/java/com/jwl/driver/server/config/RedisConfig.java b/src/main/java/com/jwl/driver/server/config/RedisConfig.java index e6da94c..f502f99 100644 --- a/src/main/java/com/jwl/driver/server/config/RedisConfig.java +++ b/src/main/java/com/jwl/driver/server/config/RedisConfig.java @@ -30,8 +30,11 @@ public class RedisConfig { serializer.setObjectMapper(mapper); redisTemplate.setValueSerializer(serializer); + redisTemplate.setHashValueSerializer(serializer); //使用StringRedisSerializer来序列化和反序列化redis的key值 - redisTemplate.setKeySerializer(new StringRedisSerializer()); + redisTemplate.setKeySerializer(serializer); + redisTemplate.setHashValueSerializer(serializer); +// redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.afterPropertiesSet(); return redisTemplate; } diff --git a/src/main/java/com/jwl/driver/server/constant/Constants.java b/src/main/java/com/jwl/driver/server/constant/Constants.java index f702683..c9e18c4 100644 --- a/src/main/java/com/jwl/driver/server/constant/Constants.java +++ b/src/main/java/com/jwl/driver/server/constant/Constants.java @@ -50,4 +50,24 @@ public class Constants { //微信支付 public static String WECHAT_PAY = "weChatPay"; + //题库版本前缀 + public static String QUESTION_VERSOPN_PREFIX = "QuestionVersion_"; + + //redis 有效期(单位秒) + public static String REDIS_EXPIRE_TIME = "RedisExprieTime"; + + //考试题型数量配置项 + public static String TEST_QUESTION_TYPE_NUM = "TestQuestionTypeNum"; + + //配置项列表前缀 + public static String CONFIG_LIST_PREFIX = "configListOf_"; + + //配置项前缀 + public static String CONFIG_PREFIX = "configOf_"; + + //专项数量前缀 + public static String SPECIAL_NUM_PREFIX= "SpecialNum_"; + + + } diff --git a/src/main/java/com/jwl/driver/server/constant/ErrorCode.java b/src/main/java/com/jwl/driver/server/constant/ErrorCode.java index 9e25272..1038c6a 100644 --- a/src/main/java/com/jwl/driver/server/constant/ErrorCode.java +++ b/src/main/java/com/jwl/driver/server/constant/ErrorCode.java @@ -31,6 +31,9 @@ public class ErrorCode { // 业务异常编码,异常原因已知 public static final String BUSINESS = "E008"; + // 题库版本异常 + public static final String VERSION_ERROR = "4001"; + public static final String NOT_SHOW = "NOO1"; private ErrorCode() { diff --git a/src/main/java/com/jwl/driver/server/controller/TdQuestionController.java b/src/main/java/com/jwl/driver/server/controller/TdQuestionController.java index 6c716e6..9adcc39 100644 --- a/src/main/java/com/jwl/driver/server/controller/TdQuestionController.java +++ b/src/main/java/com/jwl/driver/server/controller/TdQuestionController.java @@ -42,7 +42,6 @@ public class TdQuestionController { return BaseResponse.success(tdQuestionService.queryQuestionById(queryDto)); } - @ApiOperation("根据id列表获取题目") @PostMapping("/queryQuestionByIdList") public BaseResponse queryQuestionByIdList(@RequestBody QuestionQueryDto queryDto) { @@ -50,14 +49,20 @@ public class TdQuestionController { return BaseResponse.success(tdQuestionService.queryQuestionByIdList(queryDto)); } - @ApiOperation("根据查询条件获取题目") @PostMapping("/queryQuestion") public BaseResponse queryQuestion(@RequestBody QuestionQueryDto queryDto) { - log.info("获取题型======>queryDto:{}", queryDto); + log.info("根据查询条件获取题目======>queryDto:{}", queryDto); return BaseResponse.success(tdQuestionService.queryQuestion(queryDto)); } + @ApiOperation("根据查询条件获取题目Id") + @PostMapping("/queryQuestionId") + public BaseResponse queryQuestionId(@RequestBody QuestionQueryDto queryDto) { + log.info("根据查询条件获取题目Id======>queryDto:{}", queryDto); + return BaseResponse.success(tdQuestionService.queryQuestionId(queryDto)); + } + @ApiOperation("获取模拟考试题目") @PostMapping("/getTestQuestion") public BaseResponse getTestQuestion(@RequestBody QuestionQueryDto queryDto) { @@ -68,6 +73,13 @@ public class TdQuestionController { return BaseResponse.success(tdQuestionService.getTestQuestion(queryDto)); } + @ApiOperation("获取模拟考试题目Id") + @PostMapping("/getTestQuestionId") + public BaseResponse getTestQuestionId(@RequestBody QuestionQueryDto queryDto) { + log.info("根据查询条件获取题目Id======>queryDto:{}", queryDto); + return BaseResponse.success(tdQuestionService.getTestQuestionId(queryDto)); + } + @ApiOperation("题目分类") @PostMapping("/questionCategory") public BaseResponse questionCategory(@RequestBody QuestionQueryDto queryDto) { diff --git a/src/main/java/com/jwl/driver/server/controller/TdQuestionVersionController.java b/src/main/java/com/jwl/driver/server/controller/TdQuestionVersionController.java new file mode 100644 index 0000000..0d2af3b --- /dev/null +++ b/src/main/java/com/jwl/driver/server/controller/TdQuestionVersionController.java @@ -0,0 +1,56 @@ +package com.jwl.driver.server.controller; + + +import com.jwl.driver.server.dto.TestSubmitDto; +import com.jwl.driver.server.entity.TdQuestionVersion; +import com.jwl.driver.server.exception.BusinessException; +import com.jwl.driver.server.response.BaseResponse; +import com.jwl.driver.server.service.ITdQuestionVersionService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import org.springframework.stereotype.Controller; + +import javax.validation.Valid; +import java.util.Objects; + +/** + *

+ * 题库版本表; 前端控制器 + *

+ * + * @author Automated procedures + * @since 2023-09-03 + */ +@Api(tags = "题库版本") +@RestController +@RequestMapping("/tdQuestionVersion") +@Slf4j +public class TdQuestionVersionController { + + @Autowired + private ITdQuestionVersionService versionService; + + @ApiOperation("获取题库当前版本") + @GetMapping("/currentVersion") + public BaseResponse testSubmit(@RequestParam Integer carTypeId) { + log.info("获取题库当前版本======>carTypeId:{}", carTypeId); + return BaseResponse.success(versionService.currentVersion(carTypeId)); + } + + + @ApiOperation("题库版本更新") + @PostMapping("/addVersion") + public BaseResponse addVersion(@RequestBody TdQuestionVersion versionDto) { + log.info("题库版本更新======>versionDto:{}", versionDto); + if (Objects.isNull(versionDto.getCarTypeId())){ + throw new BusinessException("缺少必要参数"); + } + + return BaseResponse.success(versionService.addVersion(versionDto)); + } + +} diff --git a/src/main/java/com/jwl/driver/server/dto/QuestionQueryDto.java b/src/main/java/com/jwl/driver/server/dto/QuestionQueryDto.java index 0f63e27..cfcefab 100644 --- a/src/main/java/com/jwl/driver/server/dto/QuestionQueryDto.java +++ b/src/main/java/com/jwl/driver/server/dto/QuestionQueryDto.java @@ -140,4 +140,10 @@ public class QuestionQueryDto implements Serializable { @ApiModelProperty("是否密卷2") private Integer isExam2; + /** + * 题库版本id + */ + @ApiModelProperty("题库版本id") + private Long versionId; + } diff --git a/src/main/java/com/jwl/driver/server/dto/TestQuestionTypeDto.java b/src/main/java/com/jwl/driver/server/dto/TestQuestionTypeDto.java new file mode 100644 index 0000000..c779ecd --- /dev/null +++ b/src/main/java/com/jwl/driver/server/dto/TestQuestionTypeDto.java @@ -0,0 +1,27 @@ +package com.jwl.driver.server.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.experimental.Accessors; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * @author 曹林 + * @description 考试题目类型蚕食 + * @create 2023/8/11 22:21 + */ +@Data +@Accessors(chain = true) +public class TestQuestionTypeDto { + + //科目 + private String subject; + //判断题 + private Integer judgeNum; + //单选题 + private Integer radioNum; + //多选题 + private Integer multipleChoiceNum; +} diff --git a/src/main/java/com/jwl/driver/server/entity/TdQuestionVersion.java b/src/main/java/com/jwl/driver/server/entity/TdQuestionVersion.java new file mode 100644 index 0000000..20fb211 --- /dev/null +++ b/src/main/java/com/jwl/driver/server/entity/TdQuestionVersion.java @@ -0,0 +1,58 @@ +package com.jwl.driver.server.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import java.time.LocalDateTime; +import com.baomidou.mybatisplus.annotation.TableField; +import java.io.Serializable; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + *

+ * 题库版本表; + *

+ * + * @author Automated procedures + * @since 2023-09-03 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +public class TdQuestionVersion implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 题库版本 + */ + @TableId(value = "VERSION_ID", type = IdType.AUTO) + private Long versionId; + + /** + * 车型标识 + */ + @TableField("CAR_TYPE_ID") + private Integer carTypeId; + + /** + * 是否生效 + */ + @TableField("IS_ACTIVE") + private String isActive; + + /** + * 备注说明 + */ + @TableField("DESCRIPTION") + private String description; + + /** + * 创建时间 + */ + @TableField("CREATE_TIME") + private LocalDateTime createTime; + + +} diff --git a/src/main/java/com/jwl/driver/server/entity/TdSysConfig.java b/src/main/java/com/jwl/driver/server/entity/TdSysConfig.java index e1e5dc0..4417bf3 100644 --- a/src/main/java/com/jwl/driver/server/entity/TdSysConfig.java +++ b/src/main/java/com/jwl/driver/server/entity/TdSysConfig.java @@ -4,6 +4,11 @@ import com.baomidou.mybatisplus.annotation.TableId; import java.time.LocalDateTime; import com.baomidou.mybatisplus.annotation.TableField; import java.io.Serializable; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; @@ -77,6 +82,8 @@ public class TdSysConfig implements Serializable { * 创建时间 */ @TableField("CREATE_TIME") + @JsonDeserialize(using = LocalDateTimeDeserializer.class) + @JsonSerialize(using = LocalDateTimeSerializer.class) private LocalDateTime createTime; diff --git a/src/main/java/com/jwl/driver/server/entity/TdSysConfigList.java b/src/main/java/com/jwl/driver/server/entity/TdSysConfigList.java index 8d1eb51..8ffdb59 100644 --- a/src/main/java/com/jwl/driver/server/entity/TdSysConfigList.java +++ b/src/main/java/com/jwl/driver/server/entity/TdSysConfigList.java @@ -4,6 +4,11 @@ import com.baomidou.mybatisplus.annotation.TableId; import java.time.LocalDateTime; import com.baomidou.mybatisplus.annotation.TableField; import java.io.Serializable; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; @@ -63,6 +68,8 @@ public class TdSysConfigList implements Serializable { * 创建时间 */ @TableField("CREATE_TIME") + @JsonDeserialize(using = LocalDateTimeDeserializer.class) + @JsonSerialize(using = LocalDateTimeSerializer.class) private LocalDateTime createTime; diff --git a/src/main/java/com/jwl/driver/server/mapper/TdQuestionMapper.java b/src/main/java/com/jwl/driver/server/mapper/TdQuestionMapper.java index f7c995c..c77dc60 100644 --- a/src/main/java/com/jwl/driver/server/mapper/TdQuestionMapper.java +++ b/src/main/java/com/jwl/driver/server/mapper/TdQuestionMapper.java @@ -26,6 +26,13 @@ public interface TdQuestionMapper extends BaseMapper { */ List queryQuestion(@Param("queryDto") QuestionQueryDto queryDto); + /** + * 获取考题id + * @param queryDto + * @return + */ + List queryQuestionId(@Param("queryDto") QuestionQueryDto queryDto); + /** * 随机查询考题 * @param queryDto @@ -33,6 +40,13 @@ public interface TdQuestionMapper extends BaseMapper { */ List queryQuestionByRandom(@Param("queryDto") QuestionQueryDto queryDto); + /** + * 随机查询考题Id + * @param queryDto + * @return + */ + List queryQuestionIdByRandom(@Param("queryDto") QuestionQueryDto queryDto); + int updateQuestion(@Param("questionVo") QuestionVo questionVo); /** @@ -41,4 +55,6 @@ public interface TdQuestionMapper extends BaseMapper { * @return */ Map querySpecialNum(@Param("queryDto") QuestionQueryDto queryDto); + + } diff --git a/src/main/java/com/jwl/driver/server/mapper/TdQuestionVersionMapper.java b/src/main/java/com/jwl/driver/server/mapper/TdQuestionVersionMapper.java new file mode 100644 index 0000000..94fae88 --- /dev/null +++ b/src/main/java/com/jwl/driver/server/mapper/TdQuestionVersionMapper.java @@ -0,0 +1,16 @@ +package com.jwl.driver.server.mapper; + +import com.jwl.driver.server.entity.TdQuestionVersion; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 题库版本表; Mapper 接口 + *

+ * + * @author Automated procedures + * @since 2023-09-03 + */ +public interface TdQuestionVersionMapper extends BaseMapper { + +} diff --git a/src/main/java/com/jwl/driver/server/service/ITdQuestionService.java b/src/main/java/com/jwl/driver/server/service/ITdQuestionService.java index 474ef33..882bbfe 100644 --- a/src/main/java/com/jwl/driver/server/service/ITdQuestionService.java +++ b/src/main/java/com/jwl/driver/server/service/ITdQuestionService.java @@ -41,6 +41,13 @@ public interface ITdQuestionService extends IService { */ List queryQuestion(QuestionQueryDto queryDto); + /** + * 根据查询条件获取题目Id + * @param queryDto + * @return + */ + List queryQuestionId(QuestionQueryDto queryDto); + /** * 获取考试题目 * @param queryDto @@ -48,6 +55,13 @@ public interface ITdQuestionService extends IService { */ List getTestQuestion(QuestionQueryDto queryDto); + /** + * 获取考试题目Id + * @param queryDto + * @return + */ + List getTestQuestionId(QuestionQueryDto queryDto); + /** * 题目分类 * @param queryDto @@ -68,4 +82,5 @@ public interface ITdQuestionService extends IService { * @return */ Map querySpecialNum(QuestionQueryDto queryDto); + } diff --git a/src/main/java/com/jwl/driver/server/service/ITdQuestionVersionService.java b/src/main/java/com/jwl/driver/server/service/ITdQuestionVersionService.java new file mode 100644 index 0000000..37725a2 --- /dev/null +++ b/src/main/java/com/jwl/driver/server/service/ITdQuestionVersionService.java @@ -0,0 +1,29 @@ +package com.jwl.driver.server.service; + +import com.jwl.driver.server.entity.TdQuestionVersion; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 题库版本表; 服务类 + *

+ * + * @author Automated procedures + * @since 2023-09-03 + */ +public interface ITdQuestionVersionService extends IService { + + /** + * 获取题库当前版本号 + * @param carTypeId + * @return + */ + Long currentVersion(Integer carTypeId); + + /** + * 题库版本更新 + * @param versionDto + * @return + */ + Boolean addVersion(TdQuestionVersion versionDto); +} diff --git a/src/main/java/com/jwl/driver/server/service/impl/TdQuestionServiceImpl.java b/src/main/java/com/jwl/driver/server/service/impl/TdQuestionServiceImpl.java index 9012f20..2fe24fc 100644 --- a/src/main/java/com/jwl/driver/server/service/impl/TdQuestionServiceImpl.java +++ b/src/main/java/com/jwl/driver/server/service/impl/TdQuestionServiceImpl.java @@ -2,19 +2,30 @@ package com.jwl.driver.server.service.impl; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.generator.config.IFileCreate; +import com.google.gson.JsonObject; import com.jwl.driver.server.constant.Constants; +import com.jwl.driver.server.constant.ErrorCode; import com.jwl.driver.server.dto.QuestionQueryDto; +import com.jwl.driver.server.dto.TestQuestionTypeDto; import com.jwl.driver.server.entity.TdQuestion; +import com.jwl.driver.server.entity.TdSysConfig; import com.jwl.driver.server.entity.TdSysConfigList; +import com.jwl.driver.server.exception.BusinessException; import com.jwl.driver.server.mapper.TdQuestionMapper; +import com.jwl.driver.server.redis.RedisCache; import com.jwl.driver.server.service.ITdQuestionService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.jwl.driver.server.service.ITdQuestionVersionService; import com.jwl.driver.server.service.ITdSysConfigListService; import com.jwl.driver.server.service.ITdSysConfigService; import com.jwl.driver.server.vo.QuestionVo; import com.jwl.driver.server.vo.QusetionCategoryVo; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -30,6 +41,7 @@ import java.util.stream.Collectors; * @since 2023-08-10 */ @Service +@Slf4j public class TdQuestionServiceImpl extends ServiceImpl implements ITdQuestionService { @Autowired @@ -38,16 +50,24 @@ public class TdQuestionServiceImpl extends ServiceImpl questionVos = queryQuestion(newDto); - return CollectionUtil.isEmpty(questionVos)? null : questionVos.get(0); + return CollectionUtil.isEmpty(questionVos) ? null : questionVos.get(0); } @Override public List queryQuestionByIdList(QuestionQueryDto queryDto) { + QuestionQueryDto newDto = new QuestionQueryDto() .setQuestionIdList(queryDto.getQuestionIdList()); return queryQuestion(newDto); @@ -55,61 +75,123 @@ public class TdQuestionServiceImpl extends ServiceImpl queryQuestion(QuestionQueryDto queryDto) { + //校验题库版本是否一致 + checkQuestionVersion(queryDto.getCarTypeId(), queryDto.getVersionId()); + List questionVos = this.getBaseMapper().queryQuestion(queryDto); questionOptionHandler(questionVos); return questionVos; } + @Override + public List queryQuestionId(QuestionQueryDto queryDto) { + //校验题库版本是否一致 + checkQuestionVersion(queryDto.getCarTypeId(), queryDto.getVersionId()); + + List questionIds = this.getBaseMapper().queryQuestionId(queryDto); + return questionIds; + } + @Override public List getTestQuestion(QuestionQueryDto queryDto) { + + //校验题库版本是否一致 + checkQuestionVersion(queryDto.getCarTypeId(), queryDto.getVersionId()); + List resultList = new ArrayList<>(); - if (StrUtil.equals(Constants.SUBJECT_ONE,queryDto.getSubject())){ - //40道判断题 60道单选 每题1分 - queryDto.setType(Constants.QUESTION_TYPE_ONE) - .setNum(40); - resultList.addAll(this.getBaseMapper().queryQuestionByRandom(queryDto)); + TdSysConfig tdSysConfig = configService.queryConfigByKey(Constants.TEST_QUESTION_TYPE_NUM, queryDto.getCarTypeId()); + if (Objects.isNull(tdSysConfig)) { + log.info("config is not exist"); + throw new BusinessException("获取信息异常"); + } - queryDto.setType(Constants.QUESTION_TYPE_TWO) - .setNum(60); - resultList.addAll(this.getBaseMapper().queryQuestionByRandom(queryDto)); + List testQuestionTypeDtos = JSON.parseArray(tdSysConfig.getConfigJson(), TestQuestionTypeDto.class); + Optional optional = testQuestionTypeDtos.stream().filter(s -> StrUtil.equals(s.getSubject(), queryDto.getSubject())).findFirst(); + if (optional.isPresent()) { + TestQuestionTypeDto testQuestionTypeDto = optional.get(); + //判断题 + if (Objects.nonNull(testQuestionTypeDto.getJudgeNum()) && testQuestionTypeDto.getJudgeNum() > 0) { + queryDto.setType(Constants.QUESTION_TYPE_ONE) + .setNum(testQuestionTypeDto.getJudgeNum()); + resultList.addAll(this.getBaseMapper().queryQuestionByRandom(queryDto)); + } + //单选 + if (Objects.nonNull(testQuestionTypeDto.getRadioNum()) && testQuestionTypeDto.getRadioNum() > 0) { + queryDto.setType(Constants.QUESTION_TYPE_TWO) + .setNum(testQuestionTypeDto.getRadioNum()); + resultList.addAll(this.getBaseMapper().queryQuestionByRandom(queryDto)); + } - }else if(StrUtil.equals(Constants.SUBJECT_FOUR,queryDto.getSubject())){ - //20道判断题 20道单选 10道多选,每题2分,如果各车型不统一 可以配在数据库里 - queryDto.setType(Constants.QUESTION_TYPE_TWO) - .setNum(20); - - resultList.addAll(this.getBaseMapper().queryQuestionByRandom(queryDto)); - queryDto.setType(Constants.QUESTION_TYPE_ONE) - .setNum(20); - - resultList.addAll(this.getBaseMapper().queryQuestionByRandom(queryDto)); - queryDto.setType(Constants.QUESTION_TYPE_THREE) - .setNum(10); - resultList.addAll(this.getBaseMapper().queryQuestionByRandom(queryDto)); + //多选 + if (Objects.nonNull(testQuestionTypeDto.getMultipleChoiceNum()) && testQuestionTypeDto.getMultipleChoiceNum() > 0) { + queryDto.setType(Constants.QUESTION_TYPE_THREE) + .setNum(testQuestionTypeDto.getMultipleChoiceNum()); + resultList.addAll(this.getBaseMapper().queryQuestionByRandom(queryDto)); + } } questionOptionHandler(resultList); return resultList; } + @Override + public List getTestQuestionId(QuestionQueryDto queryDto) { + //校验题库版本是否一致 + checkQuestionVersion(queryDto.getCarTypeId(), queryDto.getVersionId()); + + List resultList = new ArrayList<>(); + + TdSysConfig tdSysConfig = configService.queryConfigByKey(Constants.TEST_QUESTION_TYPE_NUM, queryDto.getCarTypeId()); + if (Objects.isNull(tdSysConfig)) { + log.info("config is not exist"); + throw new BusinessException("获取信息异常"); + } + + List testQuestionTypeDtos = JSON.parseArray(tdSysConfig.getConfigJson(), TestQuestionTypeDto.class); + Optional optional = testQuestionTypeDtos.stream().filter(s -> StrUtil.equals(s.getSubject(), queryDto.getSubject())).findFirst(); + if (optional.isPresent()) { + TestQuestionTypeDto testQuestionTypeDto = optional.get(); + //判断题 + if (Objects.nonNull(testQuestionTypeDto.getJudgeNum()) && testQuestionTypeDto.getJudgeNum() > 0) { + queryDto.setType(Constants.QUESTION_TYPE_ONE) + .setNum(testQuestionTypeDto.getJudgeNum()); + resultList.addAll(this.getBaseMapper().queryQuestionIdByRandom(queryDto)); + } + //单选 + if (Objects.nonNull(testQuestionTypeDto.getRadioNum()) && testQuestionTypeDto.getRadioNum() > 0) { + queryDto.setType(Constants.QUESTION_TYPE_TWO) + .setNum(testQuestionTypeDto.getRadioNum()); + resultList.addAll(this.getBaseMapper().queryQuestionIdByRandom(queryDto)); + } + + //多选 + if (Objects.nonNull(testQuestionTypeDto.getMultipleChoiceNum()) && testQuestionTypeDto.getMultipleChoiceNum() > 0) { + queryDto.setType(Constants.QUESTION_TYPE_THREE) + .setNum(testQuestionTypeDto.getMultipleChoiceNum()); + resultList.addAll(this.getBaseMapper().queryQuestionIdByRandom(queryDto)); + } + } + return resultList; + } + @Override public List questionCategory(QuestionQueryDto queryDto) { List resultList = new ArrayList<>(); //获取题目 List tdQuestionVos = queryQuestionByIdList(queryDto); - if (CollectionUtil.isEmpty(tdQuestionVos)){ + if (CollectionUtil.isEmpty(tdQuestionVos)) { return resultList; } //获取分类 List categoryList = configListService.querySysConfigList(Constants.QUESTION_CATEGORY, Constants.DEFAULT_CARTYPE_ID); Map categoryMap = categoryList.stream().collect(Collectors.toMap(TdSysConfigList::getConfigItemCode, TdSysConfigList::getConfigItemName, (v1, v2) -> v1)); - Map totalMap = new HashMap<>(); - Map> errorQuestionIdMap = new HashMap<>(); + Map totalMap = new HashMap<>(); + Map> errorQuestionIdMap = new HashMap<>(); for (QuestionVo tdQuestionVo : tdQuestionVos) { String category = tdQuestionVo.getCategory(); - if (StrUtil.isBlank(category)){ + if (StrUtil.isBlank(category)) { continue; } String[] split = category.split(","); @@ -120,10 +202,10 @@ public class TdQuestionServiceImpl extends ServiceImpl errorQuestionIdList = errorQuestionIdMap.get(s); errorQuestionIdList.add(tdQuestionVo.getQuestionId()); } else { - totalMap.put(s,1); //此时集合中没有该Key,所以将该字符作为键加入到集合中 + totalMap.put(s, 1); //此时集合中没有该Key,所以将该字符作为键加入到集合中 List errorQuestionIdList = new ArrayList<>(); errorQuestionIdList.add(tdQuestionVo.getQuestionId()); - errorQuestionIdMap.put(s,errorQuestionIdList); + errorQuestionIdMap.put(s, errorQuestionIdList); } } } @@ -132,7 +214,7 @@ public class TdQuestionServiceImpl extends ServiceImpl querySpecialNum(QuestionQueryDto queryDto) { - return this.getBaseMapper().querySpecialNum(queryDto); + //校验题库版本是否一致 + checkQuestionVersion(queryDto.getCarTypeId(), queryDto.getVersionId()); + + Map resultMap = redisCache.getCacheObject(Constants.SPECIAL_NUM_PREFIX + queryDto.getCarTypeId() + "_" + queryDto.getSubject()); + if (Objects.nonNull(resultMap)) { + return resultMap; + } + resultMap = this.getBaseMapper().querySpecialNum(queryDto); + + if (CollectionUtil.isEmpty(resultMap)) { + return resultMap; + } + + TdSysConfig tdSysConfig = configService.queryConfigByKey(Constants.REDIS_EXPIRE_TIME, Constants.DEFAULT_CARTYPE_ID); + if (Objects.isNull(tdSysConfig)) { + log.info("config is not exist"); + throw new BusinessException("系统异常"); + } + // 塞入redis中 + redisCache.setCacheObject(Constants.SPECIAL_NUM_PREFIX + queryDto.getCarTypeId() + "_" + queryDto.getSubject(), resultMap, Long.parseLong(tdSysConfig.getConfigValue())); + return resultMap; } /** * 问题选项规整 */ - private void questionOptionHandler(List questionVos){ - if (CollectionUtil.isNotEmpty(questionVos)){ + private void questionOptionHandler(List questionVos) { + if (CollectionUtil.isNotEmpty(questionVos)) { for (QuestionVo questionVo : questionVos) { //如果选项A没有值 则为判断题 List optionList = new ArrayList<>(); - if (StrUtil.isBlank(questionVo.getChooseA()) || StrUtil.equals(questionVo.getType(),Constants.QUESTION_TYPE_ONE)){ - optionList.add(new QuestionVo.QuestionOption("A","正确","1")); - optionList.add(new QuestionVo.QuestionOption("B","错误","2")); - }else { + if (StrUtil.isBlank(questionVo.getChooseA()) || StrUtil.equals(questionVo.getType(), Constants.QUESTION_TYPE_ONE)) { + optionList.add(new QuestionVo.QuestionOption("A", "正确", "1")); + optionList.add(new QuestionVo.QuestionOption("B", "错误", "2")); + } else { //起码ABCD都有 - optionList.add(new QuestionVo.QuestionOption("A",questionVo.getChooseA(),"1")); - optionList.add(new QuestionVo.QuestionOption("B",questionVo.getChooseB(),"2")); - optionList.add(new QuestionVo.QuestionOption("C",questionVo.getChooseC(),"3")); - optionList.add(new QuestionVo.QuestionOption("D",questionVo.getChooseD(),"4")); + optionList.add(new QuestionVo.QuestionOption("A", questionVo.getChooseA(), "1")); + optionList.add(new QuestionVo.QuestionOption("B", questionVo.getChooseB(), "2")); + optionList.add(new QuestionVo.QuestionOption("C", questionVo.getChooseC(), "3")); + optionList.add(new QuestionVo.QuestionOption("D", questionVo.getChooseD(), "4")); - if (StrUtil.isNotBlank(questionVo.getChooseE())){ - optionList.add(new QuestionVo.QuestionOption("E",questionVo.getChooseE(),"5")); + if (StrUtil.isNotBlank(questionVo.getChooseE())) { + optionList.add(new QuestionVo.QuestionOption("E", questionVo.getChooseE(), "5")); } - if (StrUtil.isNotBlank(questionVo.getChooseF())){ - optionList.add(new QuestionVo.QuestionOption("F",questionVo.getChooseF(),"6")); + if (StrUtil.isNotBlank(questionVo.getChooseF())) { + optionList.add(new QuestionVo.QuestionOption("F", questionVo.getChooseF(), "6")); } - if (StrUtil.isNotBlank(questionVo.getChooseG())){ - optionList.add(new QuestionVo.QuestionOption("G",questionVo.getChooseG(),"7")); + if (StrUtil.isNotBlank(questionVo.getChooseG())) { + optionList.add(new QuestionVo.QuestionOption("G", questionVo.getChooseG(), "7")); } } questionVo.setOptionList(optionList); } } } + + /** + * 校验题库是否一直 + * + * @param carTypeId + * @param version + */ + private void checkQuestionVersion(Integer carTypeId, Long version) { + if (Objects.isNull(carTypeId) || Objects.isNull(version)) { + return; + } + + Long versionId = versionService.currentVersion(carTypeId); + if (!Objects.equals(versionId, version)) { + throw new BusinessException(ErrorCode.VERSION_ERROR, "题库版本不一致"); + } + } + + public static void main(String[] args) { + List testQuestionTypeDtos = new ArrayList<>(); + TestQuestionTypeDto dto1 = new TestQuestionTypeDto() + .setSubject("1") + .setJudgeNum(40) + .setRadioNum(60) + .setMultipleChoiceNum(0); + TestQuestionTypeDto dto2 = new TestQuestionTypeDto() + .setSubject("4") + .setJudgeNum(20) + .setRadioNum(20) + .setMultipleChoiceNum(10); + testQuestionTypeDtos.add(dto1); + testQuestionTypeDtos.add(dto2); + String jsonString = JSONArray.toJSONString(testQuestionTypeDtos); + System.out.println(jsonString); + + List testQuestionTypeDtos1 = JSONArray.parseArray(jsonString, TestQuestionTypeDto.class); + System.out.println(testQuestionTypeDtos1); + } } diff --git a/src/main/java/com/jwl/driver/server/service/impl/TdQuestionVersionServiceImpl.java b/src/main/java/com/jwl/driver/server/service/impl/TdQuestionVersionServiceImpl.java new file mode 100644 index 0000000..19ad4ec --- /dev/null +++ b/src/main/java/com/jwl/driver/server/service/impl/TdQuestionVersionServiceImpl.java @@ -0,0 +1,90 @@ +package com.jwl.driver.server.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.jwl.driver.server.constant.Constants; +import com.jwl.driver.server.entity.TdQuestionVersion; +import com.jwl.driver.server.entity.TdSysConfig; +import com.jwl.driver.server.exception.BusinessException; +import com.jwl.driver.server.mapper.TdQuestionVersionMapper; +import com.jwl.driver.server.redis.RedisCache; +import com.jwl.driver.server.service.ITdQuestionVersionService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.jwl.driver.server.service.ITdSysConfigService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.Objects; + +/** + *

+ * 题库版本表; 服务实现类 + *

+ * + * @author Automated procedures + * @since 2023-09-03 + */ +@Service +@Slf4j +public class TdQuestionVersionServiceImpl extends ServiceImpl implements ITdQuestionVersionService { + + @Autowired + private RedisCache redisCache; + + @Autowired + private ITdSysConfigService configService; + + @Override + public Long currentVersion(Integer carTypeId) { + + Integer value = redisCache.getCacheObject(Constants.QUESTION_VERSOPN_PREFIX + carTypeId); + + if (value !=null){ + return value.longValue(); + } + + LambdaQueryWrapper cond = new LambdaQueryWrapper() + .eq(TdQuestionVersion::getCarTypeId,carTypeId) + .eq(TdQuestionVersion::getIsActive,Constants.IS_ACTIVE_TRUE); + + TdQuestionVersion tdQuestionVersion = this.getBaseMapper().selectOne(cond); + if (Objects.isNull(tdQuestionVersion)){ + throw new BusinessException("题库版本异常"); + } + + TdSysConfig tdSysConfig = configService.queryConfigByKey(Constants.REDIS_EXPIRE_TIME, Constants.DEFAULT_CARTYPE_ID); + if (Objects.isNull(tdSysConfig)){ + log.info("config is not exist"); + throw new BusinessException("系统未知异常"); + } + // 塞入redis中 + redisCache.setCacheObject(Constants.QUESTION_VERSOPN_PREFIX + carTypeId,tdQuestionVersion.getVersionId(),Long.parseLong(tdSysConfig.getConfigValue())); + return tdQuestionVersion.getVersionId(); + } + + @Override + public Boolean addVersion(TdQuestionVersion versionDto) { + + LambdaQueryWrapper cond = new LambdaQueryWrapper() + .eq(TdQuestionVersion::getCarTypeId,versionDto.getCarTypeId()) + .eq(TdQuestionVersion::getIsActive,Constants.IS_ACTIVE_TRUE); + + TdQuestionVersion tdQuestionVersion = this.getBaseMapper().selectOne(cond); + + if (Objects.nonNull(tdQuestionVersion)){ + tdQuestionVersion.setIsActive(Constants.IS_ACTIVE_FALSE); + this.getBaseMapper().updateById(tdQuestionVersion); + } + TdQuestionVersion newVersion = new TdQuestionVersion(); + BeanUtils.copyProperties(versionDto,newVersion); + newVersion.setCreateTime(LocalDateTime.now()) + .setIsActive(Constants.IS_ACTIVE_TRUE); + this.baseMapper.insert(newVersion); + //删除原redis + redisCache.deleteObject(Constants.QUESTION_VERSOPN_PREFIX + versionDto.getCarTypeId()); + redisCache.deleteObjectLike(Constants.SPECIAL_NUM_PREFIX + versionDto.getCarTypeId() ); + return Boolean.TRUE; + } +} diff --git a/src/main/java/com/jwl/driver/server/service/impl/TdSysConfigListServiceImpl.java b/src/main/java/com/jwl/driver/server/service/impl/TdSysConfigListServiceImpl.java index c0f9681..abd9041 100644 --- a/src/main/java/com/jwl/driver/server/service/impl/TdSysConfigListServiceImpl.java +++ b/src/main/java/com/jwl/driver/server/service/impl/TdSysConfigListServiceImpl.java @@ -1,18 +1,22 @@ package com.jwl.driver.server.service.impl; +import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.jwl.driver.server.constant.Constants; +import com.jwl.driver.server.entity.TdSysConfig; import com.jwl.driver.server.entity.TdSysConfigList; +import com.jwl.driver.server.exception.BusinessException; import com.jwl.driver.server.mapper.TdSysConfigListMapper; +import com.jwl.driver.server.redis.RedisCache; import com.jwl.driver.server.service.ITdSysConfigListService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.jwl.driver.server.service.ITdSysConfigService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; /** @@ -24,17 +28,44 @@ import java.util.stream.Collectors; * @since 2023-08-10 */ @Service +@Slf4j public class TdSysConfigListServiceImpl extends ServiceImpl implements ITdSysConfigListService { + @Autowired + private RedisCache redisCache; + + @Autowired + private ITdSysConfigService configService; + @Override public List querySysConfigList(String configKey, Integer carTypeId) { + + List configLists = redisCache.getCacheObject(Constants.CONFIG_LIST_PREFIX + configKey + "_" + carTypeId); + if (CollectionUtil.isNotEmpty(configLists)) { + return configLists; + } + //redis中没有则查询数据库 LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() .eq(TdSysConfigList::getCarTypeId, carTypeId) .eq(TdSysConfigList::getConfigKey, configKey) .eq(TdSysConfigList::getIsActive, Constants.IS_ACTIVE_TRUE) .orderByAsc(TdSysConfigList::getShowOrder); + configLists = this.getBaseMapper().selectList(queryWrapper); - return this.getBaseMapper().selectList(queryWrapper); + if (CollectionUtil.isEmpty(configLists)) { + return configLists; + } + + //获取redis缓存时间 + TdSysConfig tdSysConfig = configService.queryConfigByKey(Constants.REDIS_EXPIRE_TIME, Constants.DEFAULT_CARTYPE_ID); + if (Objects.isNull(tdSysConfig)) { + log.info("config is not exist"); + throw new BusinessException("系统异常"); + } + // 塞入redis中 + redisCache.setCacheObject(Constants.CONFIG_LIST_PREFIX + configKey + "_" + carTypeId, configLists, Long.parseLong(tdSysConfig.getConfigValue())); + + return configLists; } @Override diff --git a/src/main/java/com/jwl/driver/server/service/impl/TdSysConfigServiceImpl.java b/src/main/java/com/jwl/driver/server/service/impl/TdSysConfigServiceImpl.java index 12b5d9d..1450b70 100644 --- a/src/main/java/com/jwl/driver/server/service/impl/TdSysConfigServiceImpl.java +++ b/src/main/java/com/jwl/driver/server/service/impl/TdSysConfigServiceImpl.java @@ -1,21 +1,23 @@ package com.jwl.driver.server.service.impl; import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.jwl.driver.server.constant.Constants; import com.jwl.driver.server.entity.TdSysConfig; +import com.jwl.driver.server.entity.TdSysConfigList; +import com.jwl.driver.server.exception.BusinessException; import com.jwl.driver.server.mapper.TdSysConfigMapper; +import com.jwl.driver.server.redis.RedisCache; import com.jwl.driver.server.service.ITdSysConfigService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.time.LocalDateTime; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; /** @@ -30,24 +32,50 @@ import java.util.stream.Collectors; @Slf4j public class TdSysConfigServiceImpl extends ServiceImpl implements ITdSysConfigService { + @Autowired + private RedisCache redisCache; + @Override public TdSysConfig queryConfigByKey(String configKey, Integer carTypeId) { log.info("获取系统配置参数,configKey:{}", configKey); + + TdSysConfig config = redisCache.getCacheObject(Constants.CONFIG_PREFIX + configKey + "_" + carTypeId); + if (Objects.nonNull(config)){ + return config; + } + LambdaQueryWrapper queryWrapper = new QueryWrapper().lambda() .eq(TdSysConfig::getCarTypeId,carTypeId) .eq(TdSysConfig::getConfigKey, configKey) .eq(TdSysConfig::getIsActive, Constants.IS_ACTIVE_TRUE); - return getOne(queryWrapper); + config = getOne(queryWrapper); + + if (Objects.isNull(config)){ + return config; + } + + //获取redis缓存时间 + TdSysConfig tdSysConfig = null; + if (StrUtil.equals(configKey,Constants.REDIS_EXPIRE_TIME)){ + tdSysConfig = config; + }else { + tdSysConfig = queryConfigByKey(Constants.REDIS_EXPIRE_TIME, Constants.DEFAULT_CARTYPE_ID); + } + + if (Objects.isNull(tdSysConfig)) { + log.info("config is not exist"); + throw new BusinessException("系统异常"); + } + // 塞入redis中 + redisCache.setCacheObject(Constants.CONFIG_PREFIX + configKey + "_" + carTypeId, config, Long.parseLong(tdSysConfig.getConfigValue())); + + return config; } @Override public String queryConfigValueByKey(String configKey, Integer carTypeId) { log.info("获取系统配置参数,configKey:{}", configKey); - LambdaQueryWrapper queryWrapper = new QueryWrapper().lambda() - .eq(TdSysConfig::getCarTypeId,carTypeId) - .eq(TdSysConfig::getConfigKey, configKey) - .eq(TdSysConfig::getIsActive, Constants.IS_ACTIVE_TRUE); - TdSysConfig config = getOne(queryWrapper); + TdSysConfig config = queryConfigByKey(configKey,carTypeId); if(null == config) { return null; } diff --git a/src/main/resources/mapper/TdQuestionMapper.xml b/src/main/resources/mapper/TdQuestionMapper.xml index e794f86..b1025a3 100644 --- a/src/main/resources/mapper/TdQuestionMapper.xml +++ b/src/main/resources/mapper/TdQuestionMapper.xml @@ -188,5 +188,93 @@ and IS_ACTIVE = '0' + + + diff --git a/src/main/resources/mapper/TdQuestionVersionMapper.xml b/src/main/resources/mapper/TdQuestionVersionMapper.xml new file mode 100644 index 0000000..b6464f4 --- /dev/null +++ b/src/main/resources/mapper/TdQuestionVersionMapper.xml @@ -0,0 +1,5 @@ + + + + +