From 0dfecde9ebe89ec797b273823c52e44baf056df6 Mon Sep 17 00:00:00 2001
From: 无关风月 <443237572@qq.com>
Date: 星期一, 24 六月 2024 09:51:54 +0800
Subject: [PATCH] Merge branch 'master' of http://120.76.84.145:10101/gitblit/r/java/DolphinEnglish

---
 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITUserPresentRecordService.java         |   16 +
 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TStudyServiceImpl.java             |  222 +++++++++++--
 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITStudyService.java                     |   14 
 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/dto/StudyWeekDTO.java                           |    6 
 ruoyi-service/ruoyi-study/src/main/resources/mapper/sutdy/TUserPresentRecordMapper.xml                  |    4 
 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TUserPresentRecord.java                  |   49 +++
 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TUserPresentRecordServiceImpl.java |   21 +
 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java              |    7 
 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITUserStudyService.java                 |    8 
 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TUserStudyServiceImpl.java         |   79 +++-
 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TUserServiceImpl.java              |   20 
 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TSubject.java                            |    5 
 ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/TGoodsServiceImpl.java             |   23 
 ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/controller/TGoodsController.java                |   36 +
 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TUserStudyRecord.java                    |    7 
 ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/domain/TOrder.java                              |   28 +
 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TStudyController.java                |  228 ++++++++++---
 ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java    |   22 
 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/ExitLearnVO.java                             |   15 
 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TUserController.java                 |   52 +-
 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/mapper/TUserPresentRecordMapper.java            |   16 +
 ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/vo/GoodDetailVO.java                            |   12 
 ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TIntegralRecord.java                     |   13 
 ruoyi-service/ruoyi-study/src/main/resources/mapper/sutdy/TIntegralRecordMapper.xml                     |    1 
 ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/config/RedissonConfig.java                      |    5 
 25 files changed, 709 insertions(+), 200 deletions(-)

diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java
index b3e1213..99da36f 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java
@@ -231,6 +231,13 @@
     public static final Integer SEVEN = 7;
 
     /**
+     * 数字10
+     */
+    public static final Integer TEN = 10;
+
+
+
+    /**
      * -1
      */
     public static final Integer BURDEN_ONE = -1;
diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java
index 661ab20..963d895 100644
--- a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java
+++ b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java
@@ -220,17 +220,17 @@
             String userkey = JwtUtils.getUserKeyStudy(token);
             user = redisService.getCacheObject(getTokenKeyStudy(userkey));
             // 再次判断登录状态是否已过期
-            if (null == user) {
-                throw new StudyLoginException("登录信息已过期,请重新登录!", 504);
-            }
-            // 优先判断当前账号是否已在其他设备登录
-            if (!user.getIsCanLogin()) {
-                throw new StudyLoginException("当前登录账号在其他设备登录!", 505);
-            }
-            // 再次判断登录状态是否已过期
-            if (System.currentTimeMillis() > user.getExpireTime()) {
-                throw new StudyLoginException("登录信息已过期,请重新登录!", 504);
-            }
+//            if (null == user) {
+//                throw new StudyLoginException("登录信息已过期,请重新登录!", 504);
+//            }
+//            // 优先判断当前账号是否已在其他设备登录
+//            if (!user.getIsCanLogin()) {
+//                throw new StudyLoginException("当前登录账号在其他设备登录!", 505);
+//            }
+//            // 再次判断登录状态是否已过期
+//            if (System.currentTimeMillis() > user.getExpireTime()) {
+//                throw new StudyLoginException("登录信息已过期,请重新登录!", 504);
+//            }
             return user;
         }
         return user;
diff --git a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/config/RedissonConfig.java b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/config/RedissonConfig.java
index c9a8d86..5cd7758 100644
--- a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/config/RedissonConfig.java
+++ b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/config/RedissonConfig.java
@@ -22,7 +22,10 @@
     @Bean
     public RedissonClient redissonClient() {
         Config config = new Config();
-        config.useSingleServer().setAddress("redis://127.0.0.1:6379").setPassword("123456");
+        // 线上redis
+        config.useSingleServer().setAddress("redis://127.0.0.1:6379").setPassword("dolphin123456");
+        // 本地redis
+//        config.useSingleServer().setAddress("redis://127.0.0.1:6379").setPassword("123456");
         return Redisson.create(config);
     }
 
diff --git a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/controller/TGoodsController.java b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/controller/TGoodsController.java
index 48c5d95..e335244 100644
--- a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/controller/TGoodsController.java
+++ b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/controller/TGoodsController.java
@@ -164,9 +164,9 @@
     @PostMapping("/addGoods")
     @ApiOperation(value = "添加", tags = {"后台-商品管理"})
     public R addGoods(@RequestBody TGoods dto) {
-        if (dto.getTotal()!=null){
+        if (dto.getTotal() != null) {
             dto.setSurplus(dto.getTotal());
-        }else{
+        } else {
             dto.setSurplus(0);
         }
         goodsService.save(dto);
@@ -184,9 +184,9 @@
     @PostMapping("/updateGoods")
     @ApiOperation(value = "修改", tags = {"后台-商品管理"})
     public R updateGoods(@RequestBody TGoods dto) {
-        if (dto.getTotal()!=null){
+        if (dto.getTotal() != null) {
             dto.setSurplus(dto.getTotal());
-        }else{
+        } else {
             dto.setSurplus(0);
         }
         goodsService.updateById(dto);
@@ -647,7 +647,19 @@
             number += goods.getBasicCount();
         }
         number += orderService.getGoodBuyNumber(goods.getId());
-        return R.ok(new GoodDetailVO(goods, goodsTypes, number));
+        // 剩余兑换数量
+        Integer residueNumber = null;
+        if (null != goods.getTotal()) {
+            // 计算剩余兑换数量
+            List<TOrder> orderList = orderService.lambdaQuery().eq(TOrder::getGoodsId, goodId)
+                    .eq(TOrder::getDisabled, 0).list();
+            Integer item = 0;
+            for (TOrder order : orderList) {
+                item += order.getCount();
+            }
+            residueNumber = goods.getTotal() - item;
+        }
+        return R.ok(new GoodDetailVO(goods, goodsTypes, number, residueNumber));
     }
 
     /**
@@ -678,7 +690,19 @@
             number += goods.getBasicCount();
         }
         number += orderService.getGoodBuyNumber(goods.getId());
-        return R.ok(new GoodDetailVO(goods, goodsTypes, number));
+        // 剩余兑换数量
+        Integer residueNumber = null;
+        if (null != goods.getTotal()) {
+            // 计算剩余兑换数量
+            List<TOrder> orderList = orderService.lambdaQuery().eq(TOrder::getGoodsId, goodId)
+                    .eq(TOrder::getDisabled, 0).list();
+            Integer item = 0;
+            for (TOrder order : orderList) {
+                item += order.getCount();
+            }
+            residueNumber = goods.getTotal() - item;
+        }
+        return R.ok(new GoodDetailVO(goods, goodsTypes, number, residueNumber));
     }
 
     /**
diff --git a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/domain/TOrder.java b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/domain/TOrder.java
index 7511431..68bc8c1 100644
--- a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/domain/TOrder.java
+++ b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/domain/TOrder.java
@@ -103,6 +103,10 @@
     @ApiModelProperty(value = "收货人地址")
     private String consigneeAddress;
 
+    @ApiModelProperty(value = "订单备注")
+    @TableField("remark")
+    private String remark;
+
 
     public Integer getId() {
         return id;
@@ -195,17 +199,17 @@
     @Override
     public String toString() {
         return "TOrder{" +
-        ", id=" + id +
-        ", orderNumber=" + orderNumber +
-        ", userId=" + userId +
-        ", insertTime=" + insertTime +
-        ", goodsId=" + goodsId +
-        ", count=" + count +
-        ", state=" + state +
-        ", express=" + express +
-        ", expressNumber=" + expressNumber +
-        ", expressTime=" + expressTime +
-        ", integral=" + integral +
-        "}";
+                ", id=" + id +
+                ", orderNumber=" + orderNumber +
+                ", userId=" + userId +
+                ", insertTime=" + insertTime +
+                ", goodsId=" + goodsId +
+                ", count=" + count +
+                ", state=" + state +
+                ", express=" + express +
+                ", expressNumber=" + expressNumber +
+                ", expressTime=" + expressTime +
+                ", integral=" + integral +
+                "}";
     }
 }
diff --git a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/TGoodsServiceImpl.java b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/TGoodsServiceImpl.java
index a238c85..cda7ef4 100644
--- a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/TGoodsServiceImpl.java
+++ b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/TGoodsServiceImpl.java
@@ -68,7 +68,10 @@
             String key = String.format(RedisConstants.GOOD_STOCK, goods.getId());
             List<TOrder> orderList = orderService.lambdaQuery().eq(TOrder::getGoodsId, goodId)
                     .eq(TOrder::getDisabled, 0).list();
-            int sum = orderList.stream().map(TOrder::getCount).mapToInt(Integer::intValue).sum();
+            int sum = 0;
+            if (!orderList.isEmpty()) {
+                sum = orderList.stream().map(TOrder::getCount).mapToInt(Integer::intValue).sum();
+            }
             // 计算商品剩余可兑换数量
             int number = goods.getTotal() - sum;
             if (number <= 0) {
@@ -127,9 +130,6 @@
             }
             // 兑换成功,生成订单信息、生成积分明细(积分明细需要远程调用rouyi-study服务)
             boolean result = exchangeGood(goodExchange, recipient, number, goodId, needIntegral);
-            // 扣除库存
-            result = result && this.lambdaUpdate().set(TGoods::getTotal, good.getTotal() - number)
-                    .eq(TGoods::getId, good.getId()).update();
             if (!result) {
                 semaphore.release(number);
                 return R.exchangeError("商品兑换失败!");
@@ -153,8 +153,10 @@
         // 扣除用户积分
         result = result && studyClient.exchangeIntegral(needIntegral, Constants.BURDEN).getData();
         return result;
-    }private Boolean exchangeGoodParent(GoodExchangeDTO goodExchange, Recipient recipient, Integer number,
-                                 Integer goodId, int needIntegral) {
+    }
+
+    private Boolean exchangeGoodParent(GoodExchangeDTO goodExchange, Recipient recipient, Integer number,
+                                       Integer goodId, int needIntegral) {
         // 兑换成功,生成订单信息、生成积分明细(积分明细需要远程调用rouyi-study服务)
         TOrder order = orderInfoParent(goodExchange, recipient, number, goodId, needIntegral);
         boolean result = orderService.save(order);
@@ -175,7 +177,7 @@
             return R.exchangeError("商品不存在,请稍后重试!");
         }
         LoginUserParent loginUser1 = tokenService.getLoginUser1();
-        if (null == loginUser1){
+        if (null == loginUser1) {
             return R.tokenError("登录失效");
         }
         // 校验用户积分是否足够兑换
@@ -237,13 +239,15 @@
         order.setGoodsId(goodId);
         order.setCount(number);
         order.setState(1);
+        order.setRemark(goodExchange.getRemark());
         order.setIntegral(needIntegral);
         order.setConsigneeName(recipient.getRecipient());
         order.setConsigneePhone(recipient.getRecipientPhone());
-        order.setConsigneeAddress(recipient.getAddress());
+        order.setConsigneeAddress(recipient.getProvince() + recipient.getCity() + recipient.getAddress());
         order.setDisabled(Boolean.FALSE);
         return order;
     }
+
     private TOrder orderInfoParent(GoodExchangeDTO goodExchange, Recipient recipient, Integer number, Integer goodId, int needIntegral) {
         TOrder order = new TOrder();
         order.setOrderNumber(goodExchange.getOrderNumber());
@@ -252,10 +256,11 @@
         order.setGoodsId(goodId);
         order.setCount(number);
         order.setState(1);
+        order.setRemark(goodExchange.getRemark());
         order.setIntegral(needIntegral);
         order.setConsigneeName(recipient.getRecipient());
         order.setConsigneePhone(recipient.getRecipientPhone());
-        order.setConsigneeAddress(recipient.getAddress());
+        order.setConsigneeAddress(recipient.getProvince() + recipient.getCity() + recipient.getAddress());
         order.setDisabled(Boolean.FALSE);
         return order;
     }
diff --git a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/vo/GoodDetailVO.java b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/vo/GoodDetailVO.java
index e5ca522..2f7212a 100644
--- a/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/vo/GoodDetailVO.java
+++ b/ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/vo/GoodDetailVO.java
@@ -31,12 +31,19 @@
     private List<TGoodsType> goodTypes;
 
     /**
+     * 商品剩余数量
+     */
+    @ApiModelProperty("商品剩余数量")
+    private Integer residueNumber;
+
+    /**
      * 已兑换人数
      */
     @ApiModelProperty("已兑换人数")
     private Integer exchangeNumber;
+
     /**
-     * 已兑换人数
+     * 订单编号
      */
     @ApiModelProperty("订单编号")
     private String orderNumber;
@@ -47,10 +54,11 @@
     @ApiModelProperty("用户默认收货地址(为:null则调用获取收货地址接口)")
     private Recipient recipient;
 
-    public GoodDetailVO(TGoods good, List<TGoodsType> goodTypes, Integer exchangeNumber) {
+    public GoodDetailVO(TGoods good, List<TGoodsType> goodTypes, Integer exchangeNumber, Integer residueNumber) {
         this.good = good;
         this.goodTypes = goodTypes;
         this.exchangeNumber = exchangeNumber;
+        this.residueNumber = residueNumber;
     }
 
     public GoodDetailVO(TGoods good, Recipient recipient) {
diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TStudyController.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TStudyController.java
index b96e876..a5ca771 100644
--- a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TStudyController.java
+++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TStudyController.java
@@ -79,6 +79,8 @@
     private IUserStudyRecordService studyRecordService;
     @Resource
     private ManagementClient managementClient;
+    @Resource
+    private ITUserPresentRecordService userPresentRecordService;
 
     @PostMapping("/storyList")
 //    @ApiOperation(value = "配置学习类型选择故事", tags = {"题目管理"})
@@ -751,7 +753,11 @@
             @ApiImplicitParam(value = "季度 首次进入季度quarter默认传1", name = "quarter", dataType = "Integer", required = true)
     })
     public R<List<StudyWeekDTO>> weekList(@RequestParam(defaultValue = "1") Integer type, @RequestParam Integer quarter) {
-        List<StudyWeekDTO> result = studyService.weekList(type, quarter);
+        LoginUserParent loginUserStudy = tokenService.getLoginUserStudy();
+        if (null == loginUserStudy) {
+            return R.tokenError("登录失效!");
+        }
+        List<StudyWeekDTO> result = studyService.weekList(type, quarter, loginUserStudy.getUserid());
         return R.ok(result);
     }
 
@@ -784,11 +790,39 @@
             throw new GlobalException("获取在线时间赠送积分信息失败!");
         }
         String integral = sysSet.getIntegral();
+        // 计算时间间隔
+        TUserPresentRecord record = userPresentRecordService.lambdaQuery()
+                .eq(TUserPresentRecord::getUserId, loginStudy.getUserid())
+                .orderByDesc(TUserPresentRecord::getPresentTime)
+                .eq(TUserPresentRecord::getIsDelete, 0).last("limit 1").one();
+        boolean result = true;
         TUser user = userService.lambdaQuery().eq(TUser::getId, loginStudy.getUserid())
                 .eq(TUser::getDisabled, 0).one();
-        boolean update = userService.lambdaUpdate().set(TUser::getIntegral, user.getIntegral() + Integer.parseInt(integral))
-                .eq(TUser::getId, loginStudy.getUserid()).update();
-        return R.ok(update);
+        if (null == record) {
+            // 赠送积分
+            result = userService.lambdaUpdate().set(TUser::getIntegral, user.getIntegral() + Integer.parseInt(integral))
+                    .eq(TUser::getId, loginStudy.getUserid()).update();
+            // 添加赠送积分记录
+            TUserPresentRecord data = new TUserPresentRecord();
+            data.setUserId(loginStudy.getUserid());
+            data.setPresentTime(new Date());
+            data.setIsDelete(0);
+            result = result && userPresentRecordService.save(data);
+        } else {
+            if (System.currentTimeMillis() - record.getPresentTime().getTime() >= 10 * 60 * 1000) {
+                // 赠送积分
+                result = userService.lambdaUpdate()
+                        .set(TUser::getIntegral, user.getIntegral() + Integer.parseInt(integral))
+                        .eq(TUser::getId, loginStudy.getUserid()).update();
+                // 添加赠送积分记录
+                TUserPresentRecord data = new TUserPresentRecord();
+                data.setUserId(loginStudy.getUserid());
+                data.setPresentTime(new Date());
+                data.setIsDelete(0);
+                result = result && userPresentRecordService.save(data);
+            }
+        }
+        return R.ok(result);
     }
 
     /**
@@ -828,7 +862,7 @@
                     .collect(Collectors.toList());
             result = new SubjectRecordResultVO(teamIds, topicIds, subjectRecord.getAnswerNumber(), subjectRecord.getCorrectNumber());
         } else {
-            result = new SubjectRecordResultVO();
+            result = null;
         }
         subjectRecordService.lambdaUpdate().set(TSubjectRecord::getDisabled, 0)
                 .eq(TSubjectRecord::getUserId, loginStudy.getUserid()).update();
@@ -850,28 +884,64 @@
         TUserStudy userStudy = userStudyService.lambdaQuery().eq(TUserStudy::getUserId, userid)
                 .eq(TUserStudy::getDisabled, 0).one();
         if (null == userStudy) {
-            throw new GlobalException("登录用户学习记录不存在!");
+            userStudy = createUserStudy(userid);
         }
+        Integer quarter = exitLearn.getQuarter();
+        Integer week = exitLearn.getWeek();
+        Integer day = exitLearn.getDay();
+        int schedule = exitLearn.getSchedule() == null ? 0 : exitLearn.getSchedule();
         if (userStudy.getWeek().equals(exitLearn.getWeek()) && userStudy.getDay().equals(exitLearn.getDay())) {
             // 计算完成率
-            int completionRate = exitLearn.getTopicIds().split(",").length * 5;
             Integer type = exitLearn.getType();
             // 更新用户学习完成率
-            if (Constants.ONE.equals(type) && userStudy.getListen() < completionRate) {
+            if (Constants.ONE.equals(type)) {
                 // 听音选图
-                userStudy.setListen(completionRate);
-            } else if (Constants.TWO.equals(type) && userStudy.getLook() < completionRate) {
+                List<TStudyListen> studyListens = studyListenService.listenSelectPicture(quarter, week, day);
+                int item = 0;
+                for (TStudyListen studyListen : studyListens) {
+                    item += studyListen.getSubject().split(",").length;
+                }
+                int i = (int) ((double) (exitLearn.getTopicIds().split(",").length / item) * 100);
+                if (i > userStudy.getListen()) {
+                    userStudy.setListen(100 - i);
+                }
+            } else if (Constants.TWO.equals(type)) {
                 // 看图选音
-                userStudy.setLook(completionRate);
-            } else if (Constants.THREE.equals(type) && userStudy.getInduction() < completionRate) {
+                List<TStudyLook> lookList = studyLookService.pictureSelectVoice(quarter, week, day);
+                if (!lookList.isEmpty()) {
+                    int item = lookList.size();
+                    int i = (int) ((double) (schedule / item)) * 100;
+                    if (i > userStudy.getLook()) {
+                        userStudy.setLook(100 - i);
+                    }
+                }
+            } else if (Constants.THREE.equals(type)) {
                 // 归纳排除
-                userStudy.setInduction(completionRate);
-            } else if (Constants.FOUR.equals(type) && userStudy.getAnswer() < completionRate) {
+                List<TStudyInduction> inductionList = studyInductionService.induceExclude(quarter, week, day);
+                if (!inductionList.isEmpty()) {
+                    int item = inductionList.size();
+                    int i = (int) ((double) (schedule / item)) * 100;
+                    if (i > userStudy.getInduction()) {
+                        userStudy.setInduction(100 - i);
+                    }
+                }
+            } else if (Constants.FOUR.equals(type)) {
                 // 有问有答
-                userStudy.setAnswer(completionRate);
-            } else if (Constants.FIVE.equals(type) && userStudy.getPair() < completionRate) {
+                List<TStudyAnswer> answerList = studyAnswerService.questionsAndAnswers(quarter, week, day);
+                if (answerList.size() % Constants.TWO == Constants.ZERO) {
+                    int i = (int) ((double) (schedule / (answerList.size() / 2))) * 100;
+                    if (i > userStudy.getAnswer()) {
+                        userStudy.setAnswer(100 - i);
+                    }
+                }
+            } else if (Constants.FIVE.equals(type)) {
                 // 音图相配
-                userStudy.setPair(completionRate);
+                List<TStudyPair> pairList = studyPairService.pictureMateVoice(quarter, week, day);
+                int item = pairList.size();
+                int i = (int) ((double) (schedule / item)) * 100;
+                if (i > userStudy.getPair()) {
+                    userStudy.setPair(100 - i);
+                }
             }
         }
         // 学习时长更新
@@ -903,7 +973,7 @@
         // 非会员只能查看非会员题目,会员可以查看所有题目
         List<TStudyListen> studyListens = studyListenService.listenSelectPicture(quarter, week, day);
         for (TStudyListen studyListen : studyListens) {
-            if (studyListen.getIsVip() == 1) {
+            if (studyListen.getIsVip() == 0) {
                 // 需要会员查看
                 if (!isVip) {
                     // 不是会员
@@ -934,7 +1004,7 @@
         // 非会员只能查看非会员题目,会员可以查看所有题目
         List<TStudyLook> lookList = studyLookService.pictureSelectVoice(quarter, week, day);
         for (TStudyLook studyListen : lookList) {
-            if (studyListen.getIsVip() == 1) {
+            if (studyListen.getIsVip() == 0) {
                 // 需要会员查看
                 if (!isVip) {
                     // 不是会员
@@ -965,7 +1035,7 @@
         // 非会员只能查看非会员题目,会员可以查看所有题目
         List<TStudyInduction> inductionList = studyInductionService.induceExclude(quarter, week, day);
         for (TStudyInduction studyListen : inductionList) {
-            if (studyListen.getIsVip() == 1) {
+            if (studyListen.getIsVip() == 0) {
                 // 需要会员查看
                 if (!isVip) {
                     // 不是会员
@@ -996,7 +1066,7 @@
         // 非会员只能查看非会员题目,会员可以查看所有题目
         List<TStudyAnswer> answerList = studyAnswerService.questionsAndAnswers(quarter, week, day);
         for (TStudyAnswer studyListen : answerList) {
-            if (studyListen.getIsVip() == 1) {
+            if (studyListen.getIsVip() == 0) {
                 // 需要会员查看
                 if (!isVip) {
                     // 不是会员
@@ -1027,7 +1097,7 @@
         // 非会员只能查看非会员题目,会员可以查看所有题目
         List<TStudyPair> pairList = studyPairService.pictureMateVoice(quarter, week, day);
         for (TStudyPair pair : pairList) {
-            if (pair.getIsVip() == 1) {
+            if (pair.getIsVip() == 0) {
                 // 需要会员查看
                 if (!isVip) {
                     // 不是会员
@@ -1066,6 +1136,7 @@
                 .eq(TUserStudyRecord::getWeek, completeStudy.getWeek())
                 .eq(TUserStudyRecord::getDay, completeStudy.getDay())
                 .eq(TUserStudyRecord::getType, 0)
+                .eq(TUserStudyRecord::getStudyType, completeStudy.getType())
                 .eq(TUserStudyRecord::getUserId, userId).list();
         if (list.isEmpty()) {
             obtainedIntegral = 0;
@@ -1092,18 +1163,19 @@
             record.setQuarter(completeStudy.getQuarter());
             record.setWeek(completeStudy.getWeek());
             record.setDay(completeStudy.getDay());
+            // 学习类型
+            record.setStudyType(completeStudy.getType());
             record.setObtainedIntegral(integral);
             record.setType(Constants.ZERO);
             update = update && studyRecordService.save(record);
         }
-        // 学习配置列表
-        List<TStudy> studyList = studyService.lambdaQuery().eq(TStudy::getDisabled, 0)
-                .orderByAsc(TStudy::getWeek).list();
-        if (studyList.isEmpty()) {
-            throw new GlobalException("学习配置列表未配置或数据失效!");
-        }
         // 更改学习记录
-        Boolean updateStudyRecord = userStudyService.exchangeStudyRecord(studyList, userId, completeStudy);
+        TUserStudy userStudyRecord = userStudyService.lambdaQuery().eq(TUserStudy::getUserId, userId)
+                .eq(TUserStudy::getDisabled, 0).one();
+        if (null == userStudyRecord) {
+            userStudyRecord = createUserStudy(userId);
+        }
+        Boolean updateStudyRecord = userStudyService.exchangeStudyRecord(userStudyRecord, userId, completeStudy);
         return R.ok(update && updateStudyRecord);
     }
 
@@ -1280,6 +1352,18 @@
             user.setIntegral(user.getIntegral() + availableIntegral);
             add = add && userService.updateById(user);
         }
+        // 学习时长更新
+        TUserStudy userStudy = userStudyService.lambdaQuery().eq(TUserStudy::getUserId, userid)
+                .eq(TUserStudy::getDisabled, 0).one();
+        if (null == userStudy) {
+            userStudy = createUserStudy(userid);
+        }
+        // 学习时长
+        userStudy.setTotalStudy(userStudy.getTotalStudy() + completeStudy.getUseTime());
+        userStudy.setTodayStudy(userStudy.getTodayStudy() + completeStudy.getUseTime());
+        userStudy.setWeekStudy(userStudy.getWeekStudy() + completeStudy.getUseTime());
+        userStudy.setMonthStudy(userStudy.getMonthStudy() + completeStudy.getUseTime());
+        boolean update = userStudyService.updateById(userStudy);
         // 超级记忆逻辑
         if (Constants.MEMORY.equals(completeStudy.getGameName())) {
             // 学习配置列表
@@ -1297,15 +1381,28 @@
             String rate = game.getRate().split(",")[completeStudy.getDifficulty()];
             add = add && completeStudy.getAccuracy() >= Integer.parseInt(rate);
         }
-        // 学习时长更新
-        TUserStudy userStudy = userStudyService.lambdaQuery().eq(TUserStudy::getUserId, userid)
-                .eq(TUserStudy::getDisabled, 0).one();
-        userStudy.setTotalStudy(userStudy.getTotalStudy() + completeStudy.getUseTime());
-        userStudy.setTodayStudy(userStudy.getTodayStudy() + completeStudy.getUseTime());
-        userStudy.setWeekStudy(userStudy.getWeekStudy() + completeStudy.getUseTime());
-        userStudy.setMonthStudy(userStudy.getMonthStudy() + completeStudy.getUseTime());
-        boolean update = userStudyService.updateById(userStudy);
         return R.ok(add && update);
+    }
+
+    private TUserStudy createUserStudy(Integer userid) {
+        TUserStudy userStudy = new TUserStudy();
+        userStudy.setUserId(userid);
+        // 学习周目
+        TStudy tStudy = studyService.lambdaQuery().eq(TStudy::getQuarter, Constants.ONE)
+                .orderByAsc(TStudy::getWeek).last("limit 1").one();
+        userStudy.setWeek(tStudy.getWeek());
+        userStudy.setDay(Constants.ONE);
+        userStudy.setTotalStudy(Constants.ZERO);
+        userStudy.setTodayStudy(Constants.ZERO);
+        userStudy.setWeekStudy(Constants.ZERO);
+        userStudy.setMonthStudy(Constants.ZERO);
+        userStudy.setListen(Constants.BURDEN_ONE);
+        userStudy.setLook(Constants.BURDEN_ONE);
+        userStudy.setInduction(Constants.BURDEN_ONE);
+        userStudy.setAnswer(Constants.BURDEN_ONE);
+        userStudy.setPair(Constants.BURDEN_ONE);
+        userStudyService.save(userStudy);
+        return userStudy;
     }
 
     private List<String> getSubjectId(Integer week) {
@@ -1412,10 +1509,13 @@
         // 学习时长更新
         TUserStudy userStudy = userStudyService.lambdaQuery().eq(TUserStudy::getUserId, userId)
                 .eq(TUserStudy::getDisabled, 0).one();
-        userStudy.setTotalStudy(userStudy.getTotalStudy() + studyTime);
-        userStudy.setTodayStudy(userStudy.getTodayStudy() + studyTime);
-        userStudy.setWeekStudy(userStudy.getWeekStudy() + studyTime);
-        userStudy.setMonthStudy(userStudy.getMonthStudy() + studyTime);
+        if (null == userStudy) {
+            userStudy = createUserStudy(userId);
+            userStudy.setTotalStudy(userStudy.getTotalStudy() + studyTime);
+            userStudy.setTodayStudy(userStudy.getTodayStudy() + studyTime);
+            userStudy.setWeekStudy(userStudy.getWeekStudy() + studyTime);
+            userStudy.setMonthStudy(userStudy.getMonthStudy() + studyTime);
+        }
         boolean update = userStudyService.updateById(userStudy);
         if (!update) {
             throw new GlobalException("学习时长更新失败!");
@@ -1477,23 +1577,28 @@
         // 学习记录
         TUserStudy studyRecord = userStudyService.lambdaQuery().eq(TUserStudy::getUserId, userId)
                 .eq(TUserStudy::getDisabled, 0).one();
-        // 学习时长格式转换
-        Integer todayStudy = studyRecord.getTodayStudy();
-        studyRecord.setTodayStudy(Math.round((float) todayStudy / 3600));
-        Integer weekStudy = studyRecord.getWeekStudy();
-        studyRecord.setWeekStudy(Math.round((float) weekStudy / 3600));
-        Integer monthStudy = studyRecord.getMonthStudy();
-        studyRecord.setMonthStudy(Math.round((float) monthStudy / 3600));
         // 总时长还需计算上游戏测试成绩时长
         List<TGameRecord> gameRecordList = gameRecordService.lambdaQuery().eq(TGameRecord::getUserId, userId)
                 .eq(TGameRecord::getDisabled, 0).list();
-        int sum = gameRecordList.stream().map(TGameRecord::getUseTime).mapToInt(Integer::intValue).sum();
-        Integer totalStudy = studyRecord.getTotalStudy();
-        studyRecord.setTotalStudy(Math.round((float) (totalStudy + sum) / 3600));
-        // 剩余周目
-        int size = studyService.list(new QueryWrapper<TStudy>()
-                .eq("type", 1)).size();
-        studyRecord.setSurplus(size - studyRecord.getWeek());
+        if (null != studyRecord) {
+            // 学习时长格式转换
+            Integer todayStudy = studyRecord.getTodayStudy();
+            studyRecord.setTodayStudy(Math.round((float) todayStudy / 3600));
+            Integer weekStudy = studyRecord.getWeekStudy();
+            studyRecord.setWeekStudy(Math.round((float) weekStudy / 3600));
+            Integer monthStudy = studyRecord.getMonthStudy();
+            studyRecord.setMonthStudy(Math.round((float) monthStudy / 3600));
+            // 游戏总时长
+            int sum = gameRecordList.stream().map(TGameRecord::getUseTime).mapToInt(Integer::intValue).sum();
+            Integer totalStudy = studyRecord.getTotalStudy();
+            studyRecord.setTotalStudy(Math.round((float) (totalStudy + sum) / 3600));
+            // 剩余周目
+            List<TStudy> studyList = studyService.lambdaQuery().eq(TStudy::getDisabled, 0)
+                    .eq(TStudy::getType, Constants.ONE)
+                    .orderByAsc(TStudy::getWeek).list();
+            int size = studyService.residueWeek(studyRecord,studyList);
+            studyRecord.setSurplus(size);
+        }
         return R.ok(new StudyRecordResultVO(studyRecord, gameRecordList));
     }
 
@@ -1568,7 +1673,14 @@
         if (tokenService.getLoginUserStudy() == null) {
             return R.tokenError("登录失效");
         }
-        return R.ok(integralRecordService.integralDetail(new Page<>(pageNum, pageSize), tokenService.getLoginUserStudy().getUserid(), time));
+        IPage<TIntegralRecord> page = integralRecordService.integralDetail(new Page<>(pageNum, pageSize),
+                tokenService.getLoginUserStudy().getUserid(), time);
+        for (TIntegralRecord record : page.getRecords()) {
+            if (!record.getIntegral().startsWith("-")) {
+                record.setIntegral("+" + record.getIntegral());
+            }
+        }
+        return R.ok(page);
     }
 
     @GetMapping("/integralDetailParent")
@@ -1616,6 +1728,7 @@
         integralRecord.setUpdateTime(new Date());
         return R.ok(integralRecordService.save(integralRecord));
     }
+
     @GetMapping("/addIntegralDetailParent")
 //    @ApiOperation(value = "添加-积分明细", tags = {"添加-积分明细"})
     @ApiImplicitParams({
@@ -1680,10 +1793,11 @@
         }
         return R.ok(userService.updateById(user));
     }
+
     @GetMapping("/exchangeIntegralParent")
 //    @ApiOperation(value = "用户积分变动", tags = {"用户积分变动"})
     public R<Boolean> exchangeIntegralParent(@RequestParam("integral") Integer integral, @RequestParam("method") String method) {
-        if (tokenService.getLoginUser1()==null){
+        if (tokenService.getLoginUser1() == null) {
             return R.tokenError("登录失效");
         }
         TUser user = userService.getById(tokenService.getLoginUser1().getUserid());
diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TUserController.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TUserController.java
index 4c69795..7d150a9 100644
--- a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TUserController.java
+++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TUserController.java
@@ -503,7 +503,10 @@
         if (null == userStudy) {
             TUserStudy study = new TUserStudy();
             study.setUserId(tUser1.getId());
-            study.setWeek(Constants.ONE);
+            // 学习周目
+            TStudy tStudy = studyService.lambdaQuery().eq(TStudy::getQuarter, Constants.ONE)
+                    .orderByAsc(TStudy::getWeek).last("limit 1").one();
+            study.setWeek(tStudy.getWeek());
             study.setDay(Constants.ONE);
             study.setTotalStudy(Constants.ZERO);
             study.setTodayStudy(Constants.ZERO);
@@ -564,25 +567,6 @@
         HashMap<String, Object> map = new HashMap<>();
         // 获取登录token
         map.put("token", tokenService.createTokenStudy(loginUserParent));
-        // 学习进度检查
-        TUserStudy userStudy = userStudyService.lambdaQuery().eq(TUserStudy::getUserId, user.getId())
-                .eq(TUserStudy::getDisabled, 0).one();
-        if (null == userStudy) {
-            TUserStudy study = new TUserStudy();
-            study.setUserId(user.getId());
-            study.setWeek(Constants.ONE);
-            study.setDay(Constants.ONE);
-            study.setTotalStudy(Constants.ZERO);
-            study.setTodayStudy(Constants.ZERO);
-            study.setWeekStudy(Constants.ZERO);
-            study.setMonthStudy(Constants.ZERO);
-            study.setListen(Constants.BURDEN_ONE);
-            study.setLook(Constants.BURDEN_ONE);
-            study.setInduction(Constants.BURDEN_ONE);
-            study.setAnswer(Constants.BURDEN_ONE);
-            study.setPair(Constants.BURDEN_ONE);
-            userStudyService.save(study);
-        }
         return R.ok(map);
     }
 
@@ -707,6 +691,9 @@
         }
         TUser user = userService.lambdaQuery().eq(TUser::getId, loginUserStudy.getUserid()).one();
         TUserStudy userStudy = userStudyService.lambdaQuery().eq(TUserStudy::getUserId, user.getId()).eq(TUserStudy::getDisabled, 0).one();
+        if (null == userStudy) {
+            userStudy = createUserStudy(loginUserStudy.getUserid());
+        }
         // 学习时长格式转换
         Integer todayStudy = userStudy.getTodayStudy();
         userStudy.setTodayStudy(Math.round((float) todayStudy / 3600));
@@ -722,7 +709,30 @@
         Integer totalStudy = userStudy.getTotalStudy();
         userStudy.setTotalStudy(Math.round((float) (totalStudy + sum) / 3600));
         return R.ok(new UserPersonalCenterVO(user, userStudy));
-    }@GetMapping("/userInfoParent")
+    }
+
+    private TUserStudy createUserStudy(Integer userid) {
+        TUserStudy userStudy = new TUserStudy();
+        userStudy.setUserId(userid);
+        // 学习周目
+        TStudy tStudy = studyService.lambdaQuery().eq(TStudy::getQuarter, Constants.ONE)
+                .orderByAsc(TStudy::getWeek).last("limit 1").one();
+        userStudy.setWeek(tStudy.getWeek());
+        userStudy.setDay(Constants.ONE);
+        userStudy.setTotalStudy(Constants.ZERO);
+        userStudy.setTodayStudy(Constants.ZERO);
+        userStudy.setWeekStudy(Constants.ZERO);
+        userStudy.setMonthStudy(Constants.ZERO);
+        userStudy.setListen(Constants.BURDEN_ONE);
+        userStudy.setLook(Constants.BURDEN_ONE);
+        userStudy.setInduction(Constants.BURDEN_ONE);
+        userStudy.setAnswer(Constants.BURDEN_ONE);
+        userStudy.setPair(Constants.BURDEN_ONE);
+        userStudyService.save(userStudy);
+        return userStudy;
+    }
+
+    @GetMapping("/userInfoParent")
     @ApiOperation(value = "用户详情", tags = {"家长端-用户详情"})
     public R<TUser> userInfoParent() {
         LoginUserParent loginUserStudy = tokenService.getLoginUser1();
diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TIntegralRecord.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TIntegralRecord.java
index b593a17..92f08f5 100644
--- a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TIntegralRecord.java
+++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TIntegralRecord.java
@@ -1,11 +1,15 @@
 package com.ruoyi.study.domain;
 
 import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
 import com.ruoyi.common.core.web.domain.BaseModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
+
+import java.util.Date;
 
 /**
  * <p>
@@ -54,6 +58,11 @@
     @ApiModelProperty("故事id 对应t_story_listen")
     private Integer storyId;
 
+    @ApiModelProperty("积分变动时间")
+    @TableField(exist = false)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm")
+    private Date time;
+
     /**
      * 前端用,返回积分变动类型
      *
@@ -62,4 +71,8 @@
     public String getType() {
         return integral.startsWith("-") ? "减少" : "增加";
     }
+
+    public Date getTime() {
+        return super.getCreateTime();
+    }
 }
diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TSubject.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TSubject.java
index 47e586f..10655aa 100644
--- a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TSubject.java
+++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TSubject.java
@@ -1,6 +1,7 @@
 package com.ruoyi.study.domain;
 
 import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.ruoyi.common.core.web.domain.BaseModel;
@@ -62,4 +63,8 @@
     @ApiModelProperty(value = "错误语音 多个逗号拼接")
     private String error;
 
+    @ApiModelProperty(value = "排序")
+    @TableField(exist = false)
+    private Integer sort;
+
 }
diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TUserPresentRecord.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TUserPresentRecord.java
new file mode 100644
index 0000000..11b6dc3
--- /dev/null
+++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TUserPresentRecord.java
@@ -0,0 +1,49 @@
+package com.ruoyi.study.domain;
+
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * <p>
+ * 用户赠送积分记录表
+ * </p>
+ *
+ * @author hjl
+ * @since 2024-06-20
+ */
+@Data
+@TableName("t_user_present_record")
+public class TUserPresentRecord {
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 用户id
+     */
+    @ApiModelProperty("用户id")
+    @TableField("user_id")
+    private Integer userId;
+
+    /**
+     * 赠送时间
+     */
+    @ApiModelProperty("赠送时间")
+    @TableField("present_time")
+    private Date presentTime;
+
+    /**
+     * 是否软删除
+     */
+    @ApiModelProperty("是否软删除(0:未删除;1:已删除)")
+    @TableField("is_delete")
+    private Integer isDelete;
+
+}
diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TUserStudyRecord.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TUserStudyRecord.java
index ef7e136..785e1dd 100644
--- a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TUserStudyRecord.java
+++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TUserStudyRecord.java
@@ -70,6 +70,13 @@
     private Integer type;
 
     /**
+     * 题目类型(1:听音选图;2:看图选音;3:归纳排除;4:有问有答;5:音图相配)
+     */
+    @ApiModelProperty("题目类型(1:听音选图;2:看图选音;3:归纳排除;4:有问有答;5:音图相配)")
+    @TableField("study_type")
+    private Integer studyType;
+
+    /**
      * 自主故事id
      */
     @ApiModelProperty("自主故事id")
diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/dto/StudyWeekDTO.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/dto/StudyWeekDTO.java
index 34c6d56..cf6b5a0 100644
--- a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/dto/StudyWeekDTO.java
+++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/dto/StudyWeekDTO.java
@@ -25,11 +25,15 @@
     @ApiModelProperty("study表Id")
     private String id;
 
-    public StudyWeekDTO(Integer week, Integer type, Integer quarter, String title, Integer total) {
+    @ApiModelProperty("能否进入周目学习")
+    private Boolean canStudy;
+
+    public StudyWeekDTO(Integer week, Integer type, Integer quarter, String title, Integer total,Boolean canStudy) {
         super.setWeek(week);
         super.setType(type);
         this.quarter = quarter;
         this.title = title;
         this.totalIntegral = total;
+        this.canStudy = canStudy;
     }
 }
diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/mapper/TUserPresentRecordMapper.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/mapper/TUserPresentRecordMapper.java
new file mode 100644
index 0000000..bdce60d
--- /dev/null
+++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/mapper/TUserPresentRecordMapper.java
@@ -0,0 +1,16 @@
+package com.ruoyi.study.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.study.domain.TUserPresentRecord;
+
+/**
+ * <p>
+ * 用户赠送积分记录表 Mapper 接口
+ * </p>
+ *
+ * @author 无关风月
+ * @since 2024-04-26
+ */
+public interface TUserPresentRecordMapper extends BaseMapper<TUserPresentRecord> {
+
+}
diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITStudyService.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITStudyService.java
index 4b6653e..b493ae8 100644
--- a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITStudyService.java
+++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITStudyService.java
@@ -2,7 +2,6 @@
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.ruoyi.study.domain.*;
-import com.ruoyi.study.dto.CompleteGameDTO;
 import com.ruoyi.study.dto.StudyWeekDTO;
 import com.ruoyi.study.vo.*;
 
@@ -23,9 +22,10 @@
      *
      * @param type    所属类型
      * @param quarter 季度
+     * @param userId  用户id
      * @return 列表
      */
-    List<StudyWeekDTO> weekList(Integer type, Integer quarter);
+    List<StudyWeekDTO> weekList(Integer type, Integer quarter, Integer userId);
 
     /**
      * 获取学习进度及学习时长等信息
@@ -115,11 +115,11 @@
     int computeTotalIntegral(List<String> studyIds, Integer type, Integer accuracy);
 
     /**
-     * 超级记忆正确率达到通关率标准,才能进入下一周目学习
+     * 计算剩余学习周目
      *
-     * @param game          游戏信息
-     * @param userid        用户id
-     * @param completeStudy 游戏完成信息
+     * @param studyRecord 学习进度信息
+     * @param studyList   学习配置列表
+     * @return 剩余周目
      */
-    void checkRate(TGame game, Integer userid, CompleteGameDTO completeStudy);
+    int residueWeek(TUserStudy studyRecord, List<TStudy> studyList);
 }
diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITUserPresentRecordService.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITUserPresentRecordService.java
new file mode 100644
index 0000000..bca8999
--- /dev/null
+++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITUserPresentRecordService.java
@@ -0,0 +1,16 @@
+package com.ruoyi.study.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.study.domain.TUserPresentRecord;
+
+/**
+ * <p>
+ * 用户赠送积分记录表 服务类
+ * </p>
+ *
+ * @author 无关风月
+ * @since 2024-04-26
+ */
+public interface ITUserPresentRecordService extends IService<TUserPresentRecord> {
+
+}
diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITUserStudyService.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITUserStudyService.java
index c57c97e..0af3259 100644
--- a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITUserStudyService.java
+++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITUserStudyService.java
@@ -37,12 +37,12 @@
     /**
      * 更改学习进度
      *
-     * @param studyList     学习配置列表
-     * @param userId        用户id
-     * @param completeStudy 学习情况
+     * @param userId          用户id
+     * @param completeStudy   学习情况
+     * @param userStudyRecord 学习进度
      * @return 更改结果
      */
-    Boolean exchangeStudyRecord(List<TStudy> studyList, Integer userId, CompleteStudyDTO completeStudy);
+    Boolean exchangeStudyRecord(TUserStudy userStudyRecord, Integer userId, CompleteStudyDTO completeStudy);
 
     /**
      * 超级记忆正确率达到通关率标准,才能进入下一周目学习
diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TStudyServiceImpl.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TStudyServiceImpl.java
index b77c602..e9719c5 100644
--- a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TStudyServiceImpl.java
+++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TStudyServiceImpl.java
@@ -3,9 +3,7 @@
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.common.core.constant.Constants;
 import com.ruoyi.common.core.exception.GlobalException;
-import com.ruoyi.common.core.utils.bean.BeanUtils;
 import com.ruoyi.study.domain.*;
-import com.ruoyi.study.dto.CompleteGameDTO;
 import com.ruoyi.study.dto.StudyWeekDTO;
 import com.ruoyi.study.mapper.TStudyMapper;
 import com.ruoyi.study.service.*;
@@ -56,7 +54,7 @@
     }
 
     @Override
-    public List<StudyWeekDTO> weekList(Integer type, Integer quarter) {
+    public List<StudyWeekDTO> weekList(Integer type, Integer quarter, Integer userId) {
         List<StudyWeekDTO> result = new ArrayList<>();
         // 根据季度和type查询学习配置
         List<TStudy> study = lambdaQuery().eq(TStudy::getQuarter, quarter).eq(TStudy::getType, type)
@@ -125,9 +123,41 @@
             total += storyListenList.stream().map(TStoryListen::getIntegral).mapToInt(Integer::intValue).sum();
             // 自主故事 - 看图配音
             total += storyListenList.stream().map(TStoryListen::getLookIntegral).mapToInt(Integer::intValue).sum();
-            result.add(new StudyWeekDTO(week, type, quarter, title, total));
+            // 判断周目是否可以进入学习
+            Boolean canStudy = checkWeekCanStudy(userId, item);
+            result.add(new StudyWeekDTO(week, type, quarter, title, total, canStudy));
         }
         return result;
+    }
+
+    /**
+     * @param userId 用户id
+     * @return 当前周目是否学习
+     */
+    private Boolean checkWeekCanStudy(Integer userId, TStudy study) {
+        TUserStudy userStudy = userStudyService.lambdaQuery().eq(TUserStudy::getUserId, userId)
+                .eq(TUserStudy::getDisabled, 0).one();
+        if (null == userStudy) {
+            userStudy = new TUserStudy();
+            userStudy.setUserId(userId);
+            // 学习周目
+            TStudy tStudy = this.lambdaQuery().eq(TStudy::getQuarter, Constants.ONE)
+                    .orderByAsc(TStudy::getWeek).last("limit 1").one();
+            userStudy.setWeek(tStudy.getWeek());
+            userStudy.setDay(Constants.ONE);
+            userStudy.setTotalStudy(Constants.ZERO);
+            userStudy.setTodayStudy(Constants.ZERO);
+            userStudy.setWeekStudy(Constants.ZERO);
+            userStudy.setMonthStudy(Constants.ZERO);
+            userStudy.setListen(Constants.BURDEN_ONE);
+            userStudy.setLook(Constants.BURDEN_ONE);
+            userStudy.setInduction(Constants.BURDEN_ONE);
+            userStudy.setAnswer(Constants.BURDEN_ONE);
+            userStudy.setPair(Constants.BURDEN_ONE);
+            userStudyService.save(userStudy);
+        }
+        // 学习记录所属周目大于当前学习周目,判断为已学习
+        return userStudy.getWeek() >= study.getWeek();
     }
 
     @Override
@@ -177,7 +207,6 @@
         List<List<TSubject>> subjectList = new ArrayList<>();
         for (TStudyListen studyListen : studyListens) {
             List<String> subjectIds = Arrays.stream(studyListen.getSubject().split(",")).collect(Collectors.toList());
-            Collections.shuffle(subjectIds);
             List<TSubject> list = new ArrayList<>();
             // 图片及语音集合
             for (String id : subjectIds) {
@@ -210,15 +239,18 @@
         // 语音及图片
         List<List<TSubject>> subjectList = new ArrayList<>();
         for (TStudyLook studyLook : lookList) {
+            List<String> sortList = Arrays.stream(studyLook.getSort().split(",")).collect(Collectors.toList());
             List<String> subjectIds = Arrays.stream(studyLook.getSubject().split(",")).collect(Collectors.toList());
-            Collections.shuffle(subjectIds);
             List<TSubject> list = new ArrayList<>();
             // 图片及语音集合
-            for (String id : subjectIds) {
-                TSubject data = subjectService.lambdaQuery().eq(TSubject::getId, id)
+            for (int i = 0; i < subjectIds.size(); i++) {
+                TSubject data = subjectService.lambdaQuery().eq(TSubject::getId, subjectIds.get(i))
                         .eq(TSubject::getDisabled, 0).one();
+                data.setSort(Integer.parseInt(sortList.get(i)));
                 list.add(data);
             }
+            // 根据顺序排序
+            list.sort(Comparator.comparingInt(TSubject::getSort));
             subjectList.add(list);
         }
         return new StudyLookResultVO(learnStudy, subjectList);
@@ -245,14 +277,36 @@
         List<List<TSubject>> subjectList = new ArrayList<>();
         for (TStudyInduction data : inductionList) {
             List<String> subjectIds = Arrays.stream(data.getSubject().split(",")).collect(Collectors.toList());
-            Collections.shuffle(subjectIds);
             List<TSubject> subjectLists = new ArrayList<>();
-            for (String id : subjectIds) {
+            // 第一组题 固定下标为0,1,2的题
+            for (int i = 0; i < Constants.THREE; i++) {
+                String id = subjectIds.get(i);
+                if (!id.startsWith("-")) {
+                    subjectLists.add(subjectService.getById(id));
+                }
+            }
+            for (int i = 0; i < Constants.THREE; i++) {
+                String id = subjectIds.get(i);
                 if (id.startsWith("-")) {
                     id = id.replace("-", "");
+                    subjectLists.add(subjectService.getById(id));
                 }
-                subjectLists.add(subjectService.getById(id));
             }
+            // 第二组题,固定下标为3,4的题
+            for (int i = Constants.THREE; i < Constants.FIVE; i++) {
+                String id = subjectIds.get(i);
+                if (!id.startsWith("-")) {
+                    subjectLists.add(subjectService.getById(id));
+                }
+            }
+            for (int i = Constants.THREE; i < Constants.FIVE; i++) {
+                String id = subjectIds.get(i);
+                if (id.startsWith("-")) {
+                    id = id.replace("-", "");
+                    subjectLists.add(subjectService.getById(id));
+                }
+            }
+            subjectLists.add(subjectService.getById(subjectIds.get(subjectIds.size() - 1).replace("-", "")));
             subjectList.add(subjectLists);
         }
         return new StudyInductionResultVO(learnStudy, subjectList);
@@ -297,22 +351,34 @@
         QuestionsAnswersSubjectVO oneVO = new QuestionsAnswersSubjectVO();
         TSubject one1 = subjectService.lambdaQuery().eq(TSubject::getId, subject)
                 .eq(TSubject::getDisabled, 0).one();
-        BeanUtils.copyProperties(one1, oneVO);
+        copyProperties(one1, oneVO);
         // 回答题目信息
         QuestionsAnswersSubjectVO twoVO = new QuestionsAnswersSubjectVO();
         TSubject two1 = subjectService.lambdaQuery().eq(TSubject::getId, answerSubject)
                 .eq(TSubject::getDisabled, 0).one();
-        BeanUtils.copyProperties(two1, twoVO);
+        copyProperties(two1, twoVO);
         // 判断第一组题目的问题题目及回答题目,哪个是答案
         if (Constants.ZERO.equals(one.getIsAnswer())) {
-            oneVO.setIsQuestion(0);
-            twoVO.setIsQuestion(1);
-        } else {
             oneVO.setIsQuestion(1);
             twoVO.setIsQuestion(0);
+        } else {
+            oneVO.setIsQuestion(0);
+            twoVO.setIsQuestion(1);
         }
         voList.add(oneVO);
         voList.add(twoVO);
+    }
+
+    private void copyProperties(TSubject subject, QuestionsAnswersSubjectVO vo) {
+        vo.setId(subject.getId());
+        vo.setName(subject.getName());
+        vo.setEnglish(subject.getEnglish());
+        vo.setType(subject.getType());
+        vo.setState(subject.getState());
+        vo.setImg(subject.getImg());
+        vo.setCorrect(subject.getCorrect());
+        vo.setError(subject.getError());
+        vo.setSort(subject.getSort());
     }
 
     @Override
@@ -336,7 +402,6 @@
         List<List<TSubject>> subjectList = new ArrayList<>();
         for (TStudyPair data : pair) {
             List<String> subjectIds = Arrays.stream(data.getSubject().split(",")).collect(Collectors.toList());
-            Collections.shuffle(subjectIds);
             List<TSubject> subjectLists = new ArrayList<>();
             for (String id : subjectIds) {
                 if (id.startsWith("-")) {
@@ -351,17 +416,39 @@
 
     @Override
     public int computeSchedule(TUserStudy result, Integer week) {
+        List<TStudy> studyList = this.lambdaQuery().eq(TStudy::getDisabled, 0)
+                .eq(TStudy::getType, 1)
+                .orderByAsc(TStudy::getWeek).list();
         // 基础学习进度
-        Integer listen = result.getListen();
-        Integer look = result.getLook();
-        Integer induction = result.getInduction();
-        Integer answer = result.getAnswer();
-        Integer pair = result.getPair();
         Integer day = result.getDay();
+        Integer studyWeek = result.getWeek();
+        Map<Integer, List<TStudy>> studyMap = new HashMap<>(8);
+        for (TStudy study : studyList) {
+            Integer quarter = study.getQuarter();
+            List<TStudy> itemList = studyMap.get(quarter);
+            if (null == itemList) {
+                itemList = new ArrayList<>();
+            }
+            itemList.add(study);
+            studyMap.put(quarter, itemList);
+        }
+        // 临时判断参数
+        boolean itemBool = false;
+        for (Map.Entry<Integer, List<TStudy>> map : studyMap.entrySet()) {
+            List<TStudy> list = map.getValue();
+            List<Integer> collect = list.stream().map(TStudy::getWeek).collect(Collectors.toList());
+            if (collect.contains(studyWeek)) {
+                int i = collect.indexOf(studyWeek);
+                if (collect.contains(week)) {
+                    int x = collect.indexOf(week);
+                    itemBool = i > x;
+                }
+            }
+        }
         // 默认进度为 0
         int defaultSchedule;
         // week以超过当前week,进度为 100%
-        if (result.getWeek() > week) {
+        if (itemBool) {
             defaultSchedule = 100;
         } else {
             // 根据day初始化学习进度
@@ -378,22 +465,28 @@
             } else {
                 defaultSchedule = 0;
             }
-            // 进度学习完成度计算总学习进度
-            if (!Constants.ZERO.equals(listen) && !Constants.BURDEN_ONE.equals(listen)) {
-                defaultSchedule += 4 * (100 / listen);
+            // 根据五种学习计算进度
+            Integer listen = result.getListen();
+            if (!Constants.BURDEN_ONE.equals(listen)) {
+                defaultSchedule += (int)(((double)listen / 100) * 4);
             }
-            if (!Constants.ZERO.equals(look) && !Constants.BURDEN_ONE.equals(look)) {
-                defaultSchedule += 4 * (100 / look);
+            Integer look = result.getLook();
+            if (!Constants.BURDEN_ONE.equals(look)) {
+                defaultSchedule += (int)(((double)look / 100) * 4);
             }
-            if (!Constants.ZERO.equals(induction) && !Constants.BURDEN_ONE.equals(induction)) {
-                defaultSchedule += 4 * (100 / induction);
+            Integer induction = result.getInduction();
+            if (!Constants.BURDEN_ONE.equals(induction)) {
+                defaultSchedule += (int)(((double)induction / 100) * 4);
             }
-            if (!Constants.ZERO.equals(answer) && !Constants.BURDEN_ONE.equals(answer)) {
-                defaultSchedule += 4 * (100 / answer);
+            Integer answer = result.getAnswer();
+            if (!Constants.BURDEN_ONE.equals(answer)) {
+                defaultSchedule += (int)(((double)answer / 100) * 4);
             }
-            if (!Constants.ZERO.equals(pair) && !Constants.BURDEN_ONE.equals(pair)) {
-                defaultSchedule += 4 * (100 / pair);
+            Integer pair = result.getPair();
+            if (!Constants.BURDEN_ONE.equals(pair)) {
+                defaultSchedule += (int)(((double)pair / 100) * 4);
             }
+
         }
         return defaultSchedule;
     }
@@ -443,8 +536,65 @@
     }
 
     @Override
-    public void checkRate(TGame game, Integer userid, CompleteGameDTO completeStudy) {
-
+    public int residueWeek(TUserStudy studyRecord, List<TStudy> studyList) {
+        // 已学习周目
+        int residueWeek = 0;
+        // 已学习到的周目
+        Integer studyWeek = studyRecord.getWeek();
+        // 根据季度分组封装
+        Map<Integer, List<TStudy>> studyMap = new HashMap<>(8);
+        for (TStudy study : studyList) {
+            Integer quarter = study.getQuarter();
+            List<TStudy> itemList = studyMap.get(quarter);
+            if (null == itemList) {
+                itemList = new ArrayList<>();
+            }
+            itemList.add(study);
+            studyMap.put(quarter, itemList);
+        }
+        // 顺序排序
+        Map<Integer, List<TStudy>> itemMap = new HashMap<>(8);
+        List<Integer> keyList = new ArrayList<>();
+        for (Map.Entry<Integer, List<TStudy>> map : studyMap.entrySet()) {
+            Integer key = map.getKey();
+            keyList.add(key);
+        }
+        Collections.sort(keyList);
+        for (Integer key : keyList) {
+            List<TStudy> itemList = studyMap.get(key);
+            itemMap.put(key, itemList);
+        }
+        // 计算已学习周目
+        boolean v = false;
+        for (Map.Entry<Integer, List<TStudy>> map : itemMap.entrySet()) {
+            List<TStudy> list = map.getValue();
+            for (int i = 0; i < list.size(); i++) {
+                TStudy item = list.get(i);
+                if (item.getWeek().equals(studyWeek)) {
+                    Integer listen = studyRecord.getListen();
+                    Integer answer = studyRecord.getAnswer();
+                    Integer look = studyRecord.getLook();
+                    Integer induction = studyRecord.getInduction();
+                    Integer pair = studyRecord.getPair();
+                    Integer gameDifficulty = studyRecord.getGameDifficulty();
+                    // 听音选图、看图选音、音图相配、有问有答、归纳排除的进度是否 100%,并且超级听力的游戏难度是否为2
+                    boolean isStudy = Constants.ONE_HUNDRED.equals(listen) && Constants.ONE_HUNDRED.equals(look) &&
+                            Constants.ONE_HUNDRED.equals(induction) && Constants.ONE_HUNDRED.equals(pair) &&
+                            Constants.ONE_HUNDRED.equals(answer) && Constants.TWO.equals(gameDifficulty);
+                    if (isStudy) {
+                        residueWeek++;
+                    }
+                    v = true;
+                    break;
+                } else {
+                    residueWeek++;
+                }
+            }
+            if (v) {
+                break;
+            }
+        }
+        return studyList.size() - residueWeek;
     }
 
 }
diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TUserPresentRecordServiceImpl.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TUserPresentRecordServiceImpl.java
new file mode 100644
index 0000000..989b2f3
--- /dev/null
+++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TUserPresentRecordServiceImpl.java
@@ -0,0 +1,21 @@
+package com.ruoyi.study.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.study.domain.TUserPresentRecord;
+import com.ruoyi.study.mapper.TUserPresentRecordMapper;
+import com.ruoyi.study.service.ITUserPresentRecordService;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 用户赠送积分记录表 服务实现类
+ * </p>
+ *
+ * @author 无关风月
+ * @since 2024-04-26
+ */
+@Service
+public class TUserPresentRecordServiceImpl extends ServiceImpl<TUserPresentRecordMapper, TUserPresentRecord> implements ITUserPresentRecordService {
+
+
+}
diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TUserServiceImpl.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TUserServiceImpl.java
index 100363e..d27f0d8 100644
--- a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TUserServiceImpl.java
+++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TUserServiceImpl.java
@@ -17,6 +17,7 @@
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
+import java.util.Date;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 import java.util.regex.Matcher;
@@ -89,16 +90,15 @@
 
     @Override
     public Boolean isVip() {
-//        TUser user = lambdaQuery().eq(TUser::getId, tokenService.getLoginUserStudy().getUserid())
-//                .eq(TUser::getDisabled, 0).eq(TUser::getState,1).one();
-//        // 是否为vip 逻辑
-//        if (null == user) {
-//            return false;
-//        }
-//        // vip过期时间,字段为空也表示 当前用户不是vip
-//        Date vipEndTime = user.getVipEndTime();
-//        return null != vipEndTime && System.currentTimeMillis() <= vipEndTime.getTime();
-        return true;
+        TUser user = lambdaQuery().eq(TUser::getId, tokenService.getLoginUserStudy().getUserid())
+                .eq(TUser::getDisabled, 0).eq(TUser::getState,1).one();
+        // 是否为vip 逻辑
+        if (null == user) {
+            return false;
+        }
+        // vip过期时间,字段为空也表示 当前用户不是vip
+        Date vipEndTime = user.getVipEndTime();
+        return null != vipEndTime && System.currentTimeMillis() <= vipEndTime.getTime();
     }
 
 }
diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TUserStudyServiceImpl.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TUserStudyServiceImpl.java
index eba7df6..0570cab 100644
--- a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TUserStudyServiceImpl.java
+++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TUserStudyServiceImpl.java
@@ -13,6 +13,7 @@
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -49,8 +50,6 @@
         // 游戏难度
         GAME_DIFFICULTY_MAP.put(Constants.ZERO, Constants.ONE);
         GAME_DIFFICULTY_MAP.put(Constants.ONE, Constants.TWO);
-        GAME_DIFFICULTY_MAP.put(Constants.TWO, Constants.ZERO);
-
     }
 
     @Override
@@ -88,11 +87,9 @@
     }
 
     @Override
-    public Boolean exchangeStudyRecord(List<TStudy> studyList, Integer userId, CompleteStudyDTO completeStudy) {
+    public Boolean exchangeStudyRecord(TUserStudy userStudyRecord, Integer userId, CompleteStudyDTO completeStudy) {
         Integer studyTime = completeStudy.getStudyTime();
         // 学习记录
-        TUserStudy userStudyRecord = lambdaQuery().eq(TUserStudy::getUserId, userId)
-                .eq(TUserStudy::getDisabled, 0).one();
         Integer week = userStudyRecord.getWeek();
         Integer day = userStudyRecord.getDay();
         if (week.equals(completeStudy.getWeek()) && day.equals(completeStudy.getDay())) {
@@ -116,12 +113,20 @@
                 userStudyRecord.setAnswer(Constants.ONE_HUNDRED);
                 userStudyRecord.setPair(Constants.BURDEN_ONE);
             } else if (Constants.FIVE.equals(type)) {
-                userStudyRecord.setPair(Constants.ONE_HUNDRED);
-                // type为5并且day为5应该进入游戏日
                 Integer nextDay = DAY_MAP.get(String.valueOf(userStudyRecord.getDay()));
+                // type为5并且day为5应该进入游戏日
+                if (Constants.FIVE.equals(completeStudy.getDay())) {
+                    userStudyRecord.setPair(Constants.ONE_HUNDRED);
+                    // 游戏难度初始化 0(入门难度)
+                    userStudyRecord.setGameDifficulty(Constants.ZERO);
+                } else {
+                    userStudyRecord.setListen(Constants.BURDEN_ONE);
+                    userStudyRecord.setLook(Constants.BURDEN_ONE);
+                    userStudyRecord.setInduction(Constants.BURDEN_ONE);
+                    userStudyRecord.setAnswer(Constants.BURDEN_ONE);
+                    userStudyRecord.setPair(Constants.BURDEN_ONE);
+                }
                 userStudyRecord.setDay(nextDay);
-                // 游戏难度初始化 0(入门难度)
-                userStudyRecord.setGameDifficulty(Constants.ZERO);
             }
         }
         // 更新学习时长
@@ -136,26 +141,52 @@
     @Override
     public void checkRate(TGame game, Integer userid, CompleteGameDTO completeStudy, List<TStudy> studyList) {
         String answerRate = game.getAnswerRate();
+        // 下一周目逻辑
+        int quarterItem = 1;
+        Map<Integer, List<TStudy>> studyMap = new HashMap<>(8);
+        for (TStudy study : studyList) {
+            Integer quarter = study.getQuarter();
+            List<TStudy> itemList = studyMap.get(quarter);
+            if (null == itemList) {
+                itemList = new ArrayList<>();
+            }
+            itemList.add(study);
+            studyMap.put(quarter, itemList);
+            // 记录学习季度
+            if (study.getId().equals(game.getStudyId())) {
+                quarterItem = quarter;
+            }
+        }
+        // 获取当前季度所有周目
+        List<TStudy> studyList1 = studyMap.get(quarterItem);
         // 正确率达到通关率
         if (completeStudy.getAccuracy() >= Integer.parseInt(answerRate)) {
             // 获取用户超级记忆游戏记录
             TUserStudy userStudy = this.lambdaQuery().eq(TUserStudy::getUserId, userid).one();
-            Integer nextDay = DAY_MAP.get(String.valueOf(userStudy.getDay()));
-            userStudy.setDay(nextDay);
-            if (Constants.ONE.equals(nextDay)) {
-                // 获取下一周目信息
-                int index = -1;
-                for (int i = 0; i < studyList.size(); i++) {
-                    if (studyList.get(i).getWeek().equals(userStudy.getWeek())) {
-                        index = i;
-                        break;
+            for (int i = 0; i < studyList1.size(); i++) {
+                TStudy tStudy = studyList1.get(i);
+                if (tStudy.getWeek().equals(userStudy.getWeek())) {
+                    if (studyList1.size() == 1 || i + 1 == studyList1.size() - 1) {
+                        // 是否为当前季度最后一周目
+                        List<TStudy> studyList2 = studyMap.get(quarterItem + 1);
+                        // 下一季度数据为空
+                        if (null != studyList2 && !studyList2.isEmpty()) {
+                            TStudy tStudy1 = studyList2.get(Constants.ZERO);
+                            userStudy.setWeek(tStudy1.getWeek());
+                        }
+                    } else {
+                        TStudy tStudy1 = studyList1.get(i + 1);
+                        userStudy.setWeek(tStudy1.getWeek());
                     }
                 }
-                int nextIndex = (index + 1) % studyList.size();
-                TStudy nextStudy = studyList.get(nextIndex);
-                // 更新学习进度及学习时长
-                userStudy.setWeek(nextStudy.getWeek());
             }
+            userStudy.setDay(DAY_MAP.get(String.valueOf(userStudy.getDay())));
+            userStudy.setLook(Constants.BURDEN_ONE);
+            userStudy.setPair(Constants.BURDEN_ONE);
+            userStudy.setInduction(Constants.BURDEN_ONE);
+            userStudy.setListen(Constants.BURDEN_ONE);
+            userStudy.setAnswer(Constants.BURDEN_ONE);
+            userStudy.setGameDifficulty(Constants.ZERO);
             this.updateById(userStudy);
         }
     }
@@ -168,7 +199,9 @@
             // 获取用户超级记忆游戏记录
             TUserStudy userStudy = this.lambdaQuery().eq(TUserStudy::getUserId, userid).one();
             // 更新游戏难度学习记录
-            userStudy.setGameDifficulty(GAME_DIFFICULTY_MAP.get(completeStudy.getDifficulty()));
+            if (!Constants.TWO.equals(userStudy.getGameDifficulty())) {
+                userStudy.setGameDifficulty(GAME_DIFFICULTY_MAP.get(completeStudy.getDifficulty()));
+            }
             this.updateById(userStudy);
         }
     }
diff --git a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/ExitLearnVO.java b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/ExitLearnVO.java
index df6dcd3..dc94a17 100644
--- a/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/ExitLearnVO.java
+++ b/ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/ExitLearnVO.java
@@ -3,6 +3,8 @@
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
+import javax.validation.constraints.NotNull;
+
 /**
  * @author HJL
  * @version 1.0
@@ -10,6 +12,12 @@
  */
 @Data
 public class ExitLearnVO {
+
+    /**
+     * 所属季度
+     */
+    @ApiModelProperty("所属季度")
+    private Integer quarter;
 
     /**
      * 所属week
@@ -59,4 +67,11 @@
     @ApiModelProperty("完成学习所用时长(秒)")
     private Integer studyTime;
 
+    /**
+     * 答题进度
+     */
+    @ApiModelProperty("答题进度")
+    @NotNull(message = "答题进度不能为空!")
+    private Integer schedule;
+
 }
diff --git a/ruoyi-service/ruoyi-study/src/main/resources/mapper/sutdy/TIntegralRecordMapper.xml b/ruoyi-service/ruoyi-study/src/main/resources/mapper/sutdy/TIntegralRecordMapper.xml
index c5d91f4..6426c91 100644
--- a/ruoyi-service/ruoyi-study/src/main/resources/mapper/sutdy/TIntegralRecordMapper.xml
+++ b/ruoyi-service/ruoyi-study/src/main/resources/mapper/sutdy/TIntegralRecordMapper.xml
@@ -13,5 +13,6 @@
                 and userId = #{userId}
             </if>
         </where>
+        order by createTime desc
     </select>
 </mapper>
diff --git a/ruoyi-service/ruoyi-study/src/main/resources/mapper/sutdy/TUserPresentRecordMapper.xml b/ruoyi-service/ruoyi-study/src/main/resources/mapper/sutdy/TUserPresentRecordMapper.xml
new file mode 100644
index 0000000..18ca6f4
--- /dev/null
+++ b/ruoyi-service/ruoyi-study/src/main/resources/mapper/sutdy/TUserPresentRecordMapper.xml
@@ -0,0 +1,4 @@
+<?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.ruoyi.study.mapper.TUserPresentRecordMapper">
+</mapper>

--
Gitblit v1.7.1