diff --git a/README.md b/README.md index b0a775c2a8b62c27b6ecaba2132d10b188a2073e..e0822b15623fe8a9d47e4643da243069b137bbc7 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,30 @@ # 法治小程序后端模块 -#### 练习模块 -#### 考试模块 -#### 用户模块 -#### 预约模块 -#### 法治文档学习模块 -#### 视频以及图片 -#### 评价模块 -#### 成长等级模块 +## 练习模块 + ### 随机抽取练习题 + + 用户要获取固定题型数量的题目 的 数组 + + - 查找practice_config表 数据,获取每个**题型的数量** + + - 从缓存中获取题目,如果缓存没有,则从数据库中获取保存到缓存,再从缓存中随机抽取对应题数 + + + + ### redis缓存题目策略 + + 通过查询等级、题型数据,获取全部题型,分别放到缓存set集合中 + + practice:gid:tid 命名方式存储 + + 如果没有则从数据库中使用tid 来查询相应题目放到缓存 + +## 考试模块 +## 用户模块 +## 预约模块 +## 法治文档学习模块 +## 视频以及图片 +## 评价模块 +## 成长等级模块 diff --git a/src/main/java/com/zgn/fazhi/controller/PracticeController.java b/src/main/java/com/zgn/fazhi/controller/PracticeController.java index d1f8088c8d62a67aaa3c054f1ee2cfc2d25ef869..1f3ab8fe73c70b201e445c40fc6fcad7bc592343 100644 --- a/src/main/java/com/zgn/fazhi/controller/PracticeController.java +++ b/src/main/java/com/zgn/fazhi/controller/PracticeController.java @@ -1,43 +1,62 @@ package com.zgn.fazhi.controller; +import com.alibaba.fastjson.JSON; import com.zgn.fazhi.factory.ResultFactory; +import com.zgn.fazhi.listener.BeforeExaminationListener; import com.zgn.fazhi.pojo.po.Practice; +import com.zgn.fazhi.pojo.po.PracticeConfig; import com.zgn.fazhi.result.Result; +import com.zgn.fazhi.service.PracticeConfigService; import com.zgn.fazhi.service.PracticeService; +import com.zgn.fazhi.utils.RedisUtil; import io.swagger.annotations.ApiOperation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; +import javax.websocket.server.PathParam; import java.util.ArrayList; import java.util.List; +import java.util.Set; /** * 练习模块 + * * @author Y121 */ @RestController public class PracticeController { + + private static final Logger LOGGER = LoggerFactory.getLogger(PracticeController.class); + + @Autowired + private PracticeService practiceService; + @Autowired - PracticeService practiceService; + private PracticeConfigService practiceConfigService; + + @Autowired + private RedisUtil redisUtil; @ApiOperation("根据类型查找练习题") @GetMapping("/api/pratype") - public Result selectType(int id){ + public Result selectType(int id) { return ResultFactory.buildSuccessResult(practiceService.selectByType(id)); } @ApiOperation("查找所有的练习题") @GetMapping("/api/praall") - public Result selectAll(){ + public Result selectAll() { return ResultFactory.buildSuccessResult(practiceService.selectAllPaper()); } @ApiOperation("根据年级查找练习题") @GetMapping("/api/pragrade") - public Result selectGrade(int id){ + public Result selectGrade(int id) { return ResultFactory.buildSuccessResult(practiceService.selectByGrade(id)); } @@ -50,7 +69,7 @@ public class PracticeController { @ApiOperation("根据Id批量练习题") @GetMapping("/api/pradel") - public Result deleteId(@RequestParam(value = "id") String id){ + public Result deleteId(@RequestParam(value = "id") String id) { String[] gpIds = id.split(","); List list = new ArrayList<>(); for (String str : gpIds) { @@ -62,14 +81,61 @@ public class PracticeController { @ApiOperation("增加练习题") @PostMapping("/api/praadd") - public Result add(@RequestBody Practice practice){ + public Result add(@RequestBody Practice practice) { return practiceService.addPaper(practice); } @ApiOperation("根据Id修改练习题") @PostMapping("/api/praupdate") - public Result updateId(@RequestBody Practice practice){ + public Result updateId(@RequestBody Practice practice) { return practiceService.updatePaperById(practice); } + + + /** + * 随机获取练习题,根据一定指定规则获取固定题型题数的随机题目 + * + * @return 返回题目数组 + */ + @ApiOperation("获取不同等级的随机练习题") + @PostMapping("/api/getRandomPractice/{gid}") + public Result getRandomPractice(@PathVariable Integer gid) { + // 创建数组存储返回前端的全部题目 + ArrayList practices = new ArrayList<>(); + // 查找practice_config表 数据,获取每个题型的数量 + List allConfig = practiceConfigService.getAllConfig(); + // 查找redis缓存中是否有所有题型的题目 + for (PracticeConfig practiceConfig : allConfig) { + // 获取所有的题型,查找redis中有无该题型的题目数据 + Integer tid = practiceConfig.getTid(); + String key = "practice:" + gid + ":" + tid; + LOGGER.info("当前key值为: " + key); + if (redisUtil.hasKey(key)) { + // 如果redis缓存中有该题型数据,从题型中随机获取指定数量题目装入数组中 + LOGGER.info("读取数量为 : " + practiceConfig.getNumber()); + Set objects1 = redisUtil.sRandom(key, practiceConfig.getNumber()); + LOGGER.info("redis缓存中取出题型" + tid + "和等级为" + gid + " 的数据 : " + JSON.toJSONString(objects1)); + LOGGER.info("返回数量为 " + objects1.size()); + practices.addAll(objects1); + } else { + // 如果redis没有该数据,则要从数据库中查去并放入缓存中 + // 需要查询gid和pid相等练习题放入数组中 + List practiceList = practiceService.findPracticeByGidAndTid(gid, tid); + // 放入缓存中 + redisUtil.sListSet(key, practiceList); + LOGGER.info("成功放入缓存"); + // 取出缓存随机题数 + LOGGER.info("读取数量为 : " + practiceConfig.getNumber().longValue()); + Set objects1 = redisUtil.sRandom(key, practiceConfig.getNumber()); + LOGGER.info("redis缓存中取出题型" + tid + "和等级为" + gid + " 的数据 : " + JSON.toJSONString(objects1)); + LOGGER.info("返回数量为 " + objects1.size()); + practices.addAll(objects1); + } + + + } + return ResultFactory.buildSuccessResult(practices); + } + } diff --git a/src/main/java/com/zgn/fazhi/mapper/PracticeConfigMapper.java b/src/main/java/com/zgn/fazhi/mapper/PracticeConfigMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..46460b5e82e874f4fdd7d4e0df4bcf1b46cd42a4 --- /dev/null +++ b/src/main/java/com/zgn/fazhi/mapper/PracticeConfigMapper.java @@ -0,0 +1,12 @@ +package com.zgn.fazhi.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zgn.fazhi.pojo.po.PracticeConfig; +import org.springframework.stereotype.Repository; + +/** + * @author ydw + */ +@Repository +public interface PracticeConfigMapper extends BaseMapper { +} diff --git a/src/main/java/com/zgn/fazhi/pojo/po/PracticeConfig.java b/src/main/java/com/zgn/fazhi/pojo/po/PracticeConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..c4bc4611dc912b2e76fc7b1f5c3aa9dbb4788f59 --- /dev/null +++ b/src/main/java/com/zgn/fazhi/pojo/po/PracticeConfig.java @@ -0,0 +1,32 @@ +package com.zgn.fazhi.pojo.po; + + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 练习题配置,主要配置用户练习每次获取的题型题数的数据 + * @author ydw + */ +@Data +@EqualsAndHashCode(callSuper = false) +@ApiModel(value="练习题配置", description="") +public class PracticeConfig { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "练习题配置主键id") + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty(value = "练习题题型") + private Integer tid; + + @ApiModelProperty(value = "该题型的数量") + private Integer number; + +} diff --git a/src/main/java/com/zgn/fazhi/service/PracticeConfigService.java b/src/main/java/com/zgn/fazhi/service/PracticeConfigService.java new file mode 100644 index 0000000000000000000000000000000000000000..662158ed39ebfe75551e2528d101ea5dc81c0341 --- /dev/null +++ b/src/main/java/com/zgn/fazhi/service/PracticeConfigService.java @@ -0,0 +1,19 @@ +package com.zgn.fazhi.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.zgn.fazhi.pojo.po.PracticeConfig; + +import java.util.List; + +/** + * @author Y121 + */ +public interface PracticeConfigService extends IService { + + /** + * 获取练习题配置 + * @return 练习题配置数组 + */ + List getAllConfig(); + +} diff --git a/src/main/java/com/zgn/fazhi/service/PracticeService.java b/src/main/java/com/zgn/fazhi/service/PracticeService.java index 39a446095804ac6410a4d462f584c4abe2f50fa2..810a3ba4d6e8ab91c4e5ac8f3c865712e949a675 100644 --- a/src/main/java/com/zgn/fazhi/service/PracticeService.java +++ b/src/main/java/com/zgn/fazhi/service/PracticeService.java @@ -38,4 +38,12 @@ public interface PracticeService extends IService { */ void addPracticeList(List> list); + /** + * 通过gid和tid查询出所有练习题 + * @param gid 等级id + * @param tid 题型id + * @return 返回练习题数组 + */ + List findPracticeByGidAndTid(Integer gid, Integer tid); + } diff --git a/src/main/java/com/zgn/fazhi/service/impl/PracticeConfigServiceImpl.java b/src/main/java/com/zgn/fazhi/service/impl/PracticeConfigServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..c6ca829489aad404a99c557a8959f67936038c83 --- /dev/null +++ b/src/main/java/com/zgn/fazhi/service/impl/PracticeConfigServiceImpl.java @@ -0,0 +1,25 @@ +package com.zgn.fazhi.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.zgn.fazhi.mapper.PracticeConfigMapper; +import com.zgn.fazhi.pojo.po.PracticeConfig; +import com.zgn.fazhi.service.PracticeConfigService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @author ydw + */ +@Service +public class PracticeConfigServiceImpl extends ServiceImpl implements PracticeConfigService { + + @Autowired + private PracticeConfigMapper practiceConfigMapper; + + @Override + public List getAllConfig() { + return practiceConfigMapper.selectList(null); + } +} diff --git a/src/main/java/com/zgn/fazhi/service/impl/PracticeServiceImpl.java b/src/main/java/com/zgn/fazhi/service/impl/PracticeServiceImpl.java index abeee9da75cf6efcbeaf6831b021e1d557e54c59..4c3bc03f9b0b62604564748b50baab5206f0f30f 100644 --- a/src/main/java/com/zgn/fazhi/service/impl/PracticeServiceImpl.java +++ b/src/main/java/com/zgn/fazhi/service/impl/PracticeServiceImpl.java @@ -16,9 +16,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.Date; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.List; @@ -119,4 +117,20 @@ public class PracticeServiceImpl extends ServiceImpl i } } + + /** + * 通过gid和tid查询出所有练习题 + * @param gid 等级id + * @param tid 题型id + * @return 返回练习题数组 + */ + @Override + public List findPracticeByGidAndTid(Integer gid, Integer tid) { + QueryWrapper practiceQueryWrapper = new QueryWrapper<>(); + HashMap map = new HashMap<>(); + map.put("type_id", tid); + map.put("grade_id", gid); + practiceQueryWrapper.allEq(map); + return practiceMapper.selectList(practiceQueryWrapper); + } } diff --git a/src/main/java/com/zgn/fazhi/utils/RedisUtil.java b/src/main/java/com/zgn/fazhi/utils/RedisUtil.java index 7639e2f89cbb6edcaf405e0ca648a84bb56c75e8..8cae3575596b92c472e2c79ddc385ca100364c0b 100644 --- a/src/main/java/com/zgn/fazhi/utils/RedisUtil.java +++ b/src/main/java/com/zgn/fazhi/utils/RedisUtil.java @@ -348,6 +348,22 @@ public class RedisUtil { } } + /** + * 随机获取set集合中的元素 + * @param key set集合的key值 + * @param count 获取数量 + * @return 返回随机元素的数组 + */ + public Set sRandom(String key, int count){ + try { + return redisTemplate.opsForSet().distinctRandomMembers(key, count); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** * 将数据放入set缓存 * @@ -364,6 +380,21 @@ public class RedisUtil { } } + /** + * 将数组的数据添加入set中 + * @param key key值 + * @param list 要存放的list数据 + */ + public void sListSet(String key, List list){ + try { + for (Object o : list) { + redisTemplate.opsForSet().add(key, o); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + /** * 将set数据放入缓存 * diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties index 7d8f927893ab70f73c2fd31c8d2aee8a4523a2e5..081af6651e736196d107e76e8e5284c7eb414f42 100644 --- a/src/main/resources/application-dev.properties +++ b/src/main/resources/application-dev.properties @@ -3,4 +3,4 @@ server.port=8082 spring.datasource.url=jdbc:mysql://localhost:3306/fazhi?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT # ���ݿ��û���&���룺 spring.datasource.username=root -spring.datasource.password=root +spring.datasource.password=zgn12.21