无关风月
2024-06-24 0dfecde9ebe89ec797b273823c52e44baf056df6
Merge branch 'master' of http://120.76.84.145:10101/gitblit/r/java/DolphinEnglish
20个文件已修改
5个文件已添加
841 ■■■■ 已修改文件
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/config/RedissonConfig.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/controller/TGoodsController.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/domain/TOrder.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/TGoodsServiceImpl.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/vo/GoodDetailVO.java 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TStudyController.java 200 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TUserController.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TIntegralRecord.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TSubject.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TUserPresentRecord.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TUserStudyRecord.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/dto/StudyWeekDTO.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/mapper/TUserPresentRecordMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITStudyService.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITUserPresentRecordService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITUserStudyService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TStudyServiceImpl.java 226 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TUserPresentRecordServiceImpl.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TUserServiceImpl.java 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TUserStudyServiceImpl.java 75 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/ExitLearnVO.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/resources/mapper/sutdy/TIntegralRecordMapper.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/resources/mapper/sutdy/TUserPresentRecordMapper.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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;
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;
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);
    }
ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/controller/TGoodsController.java
@@ -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));
    }
    /**
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;
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,7 +153,9 @@
        // 扣除用户积分
        result = result && studyClient.exchangeIntegral(needIntegral, Constants.BURDEN).getData();
        return result;
    }private Boolean exchangeGoodParent(GoodExchangeDTO goodExchange, Recipient recipient, Integer number,
    }
    private Boolean exchangeGoodParent(GoodExchangeDTO goodExchange, Recipient recipient, Integer number,
                                 Integer goodId, int needIntegral) {
        // 兑换成功,生成订单信息、生成积分明细(积分明细需要远程调用rouyi-study服务)
        TOrder order = orderInfoParent(goodExchange, recipient, number, goodId, needIntegral);
@@ -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;
    }
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) {
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))
        if (null == record) {
            // 赠送积分
            result = userService.lambdaUpdate().set(TUser::getIntegral, user.getIntegral() + Integer.parseInt(integral))
                .eq(TUser::getId, loginStudy.getUserid()).update();
        return R.ok(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();
        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,6 +1577,10 @@
        // 学习记录
        TUserStudy studyRecord = userStudyService.lambdaQuery().eq(TUserStudy::getUserId, userId)
                .eq(TUserStudy::getDisabled, 0).one();
        // 总时长还需计算上游戏测试成绩时长
        List<TGameRecord> gameRecordList = gameRecordService.lambdaQuery().eq(TGameRecord::getUserId, userId)
                .eq(TGameRecord::getDisabled, 0).list();
        if (null != studyRecord) {
        // 学习时长格式转换
        Integer todayStudy = studyRecord.getTodayStudy();
        studyRecord.setTodayStudy(Math.round((float) todayStudy / 3600));
@@ -1484,16 +1588,17 @@
        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());
            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,6 +1793,7 @@
        }
        return R.ok(userService.updateById(user));
    }
    @GetMapping("/exchangeIntegralParent")
//    @ApiOperation(value = "用户积分变动", tags = {"用户积分变动"})
    public R<Boolean> exchangeIntegralParent(@RequestParam("integral") Integer integral, @RequestParam("method") String method) {
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();
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();
    }
}
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;
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TUserPresentRecord.java
New file
@@ -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;
}
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")
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;
    }
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/mapper/TUserPresentRecordMapper.java
New file
@@ -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> {
}
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);
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITUserPresentRecordService.java
New file
@@ -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> {
}
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 userStudyRecord 学习进度
     * @return 更改结果
     */
    Boolean exchangeStudyRecord(List<TStudy> studyList, Integer userId, CompleteStudyDTO completeStudy);
    Boolean exchangeStudyRecord(TUserStudy userStudyRecord, Integer userId, CompleteStudyDTO completeStudy);
    /**
     * 超级记忆正确率达到通关率标准,才能进入下一周目学习
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) {
                if (id.startsWith("-")) {
                    id = id.replace("-", "");
                }
            // 第一组题 固定下标为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));
                }
            }
            // 第二组题,固定下标为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;
    }
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TUserPresentRecordServiceImpl.java
New file
@@ -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 {
}
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();
    }
}
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()));
                userStudyRecord.setDay(nextDay);
                // 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);
            }
        }
        // 更新学习时长
@@ -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();
            // 更新游戏难度学习记录
            if (!Constants.TWO.equals(userStudy.getGameDifficulty())) {
            userStudy.setGameDifficulty(GAME_DIFFICULTY_MAP.get(completeStudy.getDifficulty()));
            }
            this.updateById(userStudy);
        }
    }
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;
}
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>
ruoyi-service/ruoyi-study/src/main/resources/mapper/sutdy/TUserPresentRecordMapper.xml
New file
@@ -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>