hjl
2024-06-17 e11362ca4849da567a77d8b5e5be510df9fb0741
fix: 学习端bug
1 文件已重命名
39个文件已修改
15个文件已添加
1831 ■■■■ 已修改文件
ruoyi-api/ruoyi-api-management/src/main/java/com/ruoyi/management/api/feignClient/ManagementClient.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-study/src/main/java/com/ruoyi/study/api/factory/StudyFallbackFactory.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-study/src/main/java/com/ruoyi/study/api/feignClient/StudyClient.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-study/src/main/java/com/ruoyi/study/api/vo/UserPersonalCenterVO.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/controller/TGoodsController.java 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/IRecipientService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/RecipientServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/RegionServiceImpl.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/TGoodsServiceImpl.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/config/DataUpdateHandlerConfig.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TStudyController.java 389 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TUserController.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TStudyListen.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TSubjectRecord.java 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TUserStudy.java 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TUserStudyRecord.java 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/dto/CompleteStudyDTO.java 33 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/dto/StudyWeekDTO.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/mapper/TStoryListenMapper.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/mapper/UserStudyRecordMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITGameService.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITStoryListenService.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITStoryService.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITStudyService.java 26 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITSubjectRecordService.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/IUserStudyRecordService.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TGameServiceImpl.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TStoryListenServiceImpl.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TStoryServiceImpl.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TStudyServiceImpl.java 429 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TSubjectRecordServiceImpl.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TUserServiceImpl.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TUserStudyServiceImpl.java 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/UserStudyRecordServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/ExitLearnVO.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/GameMemoryPhotoVO.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/GameMemoryVoiceVO.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/LearnStudyVO.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/QuestionsAnswersSubjectVO.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyAnswerResultVO.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyGameMemoryVO.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyGameResultVO.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyInductionResultVO.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyListenResultVO.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyLookResultVO.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyModelVO.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyPairResultVO.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyRecordVO.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyStoryListenResultVO.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyStoryVO.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/SubjectRecordResultVO.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/UserPersonalCenterVO.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/resources/mapper/sutdy/TStudyMapper.xml 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/resources/mapper/sutdy/UserStudyRecordMapper.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-management/src/main/java/com/ruoyi/management/api/feignClient/ManagementClient.java
@@ -41,9 +41,9 @@
    R<TSysSet> shareInfo();
    /**
     * 获取分享图片、标题及可获积分数
     * 获取正确及错误提示音效
     *
     * @return 获取分享图片、标题及可获积分数
     * @return 获取正确及错误提示音效
     */
    @GetMapping("/tSysSet/promptVoice")
    R<TSysSet> promptVoice();
ruoyi-api/ruoyi-api-study/src/main/java/com/ruoyi/study/api/factory/StudyFallbackFactory.java
@@ -131,7 +131,7 @@
            }
            @Override
            public R<TUser> userInfo() {
            public R<UserPersonalCenterVO> userInfo() {
                return R.fail("获取用户信息失败" + cause.getMessage());
            }
ruoyi-api/ruoyi-api-study/src/main/java/com/ruoyi/study/api/feignClient/StudyClient.java
@@ -175,14 +175,9 @@
    @PostMapping("/base/tStory/updateState/{id}/{state}")
    R updateState1(@PathVariable("id") Integer id, @PathVariable("state") Integer state);
    /**
     * 获取用户信息
     *
     * @return 用户信息
     */
    @GetMapping("/base/user/userInfo")
    @ApiOperation(value = "用户详情", tags = {"用户详情"})
    R<TUser> userInfo();
    @ApiOperation(value = "用户详情", tags = {"学习端-用户详情"})
    R<UserPersonalCenterVO> userInfo();
    /**
     * 生成积分明细-用于远程调用
ruoyi-api/ruoyi-api-study/src/main/java/com/ruoyi/study/api/vo/UserPersonalCenterVO.java
New file
@@ -0,0 +1,29 @@
package com.ruoyi.study.api.vo;
import com.ruoyi.study.api.domain.TUser;
import com.ruoyi.study.api.model.TUserStudy;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * @author HJL
 * @version 1.0
 * @since 2024-06-04 9:38
 */
@Data
public class UserPersonalCenterVO {
    @ApiModelProperty("用户信息")
    private TUser user;
    @ApiModelProperty("用户学习信息(学习时长、学习进度)")
    private TUserStudy userStudy;
    public UserPersonalCenterVO(TUser user, TUserStudy userStudy) {
        this.user = user;
        this.userStudy = userStudy;
    }
    public UserPersonalCenterVO() {
    }
}
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java
@@ -231,6 +231,11 @@
    public static final Integer SEVEN = 7;
    /**
     * -1
     */
    public static final Integer BURDEN_ONE = -1;
    /**
     * 1数字
     */
    public static final Integer ONE_HUNDRED = 100;
@@ -293,16 +298,16 @@
    /**
     * 积分来源 - 完成听故事
     */
    public static final String COMPLETE_STORY= "完成听故事";
    public static final String COMPLETE_STORY = "完成听故事";
    /**
     * 超级听力
     */
    public static final String HEARING= "超级听力";
    public static final String HEARING = "超级听力";
    /**
     * 超级听力
     */
    public static final String MEMORY= "超级记忆";
    public static final String MEMORY = "超级记忆";
}
ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/controller/TGoodsController.java
@@ -3,7 +3,9 @@
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.exception.GlobalException;
import com.ruoyi.common.core.utils.bean.BeanUtils;
import com.ruoyi.common.core.web.page.PageInfo;
import com.ruoyi.common.security.service.TokenService;
@@ -16,6 +18,7 @@
import com.ruoyi.goods.vo.TOrderVO;
import com.ruoyi.study.api.domain.TUser;
import com.ruoyi.study.api.feignClient.StudyClient;
import com.ruoyi.system.api.model.LoginUserParent;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
@@ -95,12 +98,11 @@
    }
    @PostMapping("/goodListStudy")
    @ApiOperation(value = "商品列表查询", tags = {"学习端"})
    @ApiOperation(value = "商品列表查询", tags = {"学习端-商城"})
    public R<PageInfo<TGoods>> goodListStudy(@RequestBody GoodQueryDTO goodQuery) {
        if (tokenService.getLoginUserStudy() == null) {
            return R.tokenError("登录失效");
        }
        List<String> type = goodQuery.getType();
        String keywords = goodQuery.getKeywords();
        // 初始化条件构造器
        QueryWrapper<TGoods> wrapper = new QueryWrapper<>();
@@ -108,7 +110,6 @@
        // 类型匹配 todo
        if (goodQuery.getType() != null && goodQuery.getType().size() > 0) {
            StringBuilder temp = new StringBuilder("");
            for (String s : goodQuery.getType()) {
                wrapper.or().apply("FIND_IN_SET('" + s + "', typeIds)"); // 将每个类型 ID 应用于 FIND_IN_SET 函数
            }
@@ -224,7 +225,7 @@
    @GetMapping("/exchangeRecordParent")
    @ApiOperation(value = "家长端-兑换记录", tags = {"家长端-兑换记录"})
    public R<Page<TOrder>> exchangeRecordParent(Integer pageNumber, Integer pageSize) {
        if (tokenService.getLoginUser1() == null){
        if (tokenService.getLoginUser1() == null) {
            return R.tokenError("登录失效");
        }
        Page<TOrder> page = orderService.page(new Page<>(pageNumber, pageSize), new QueryWrapper<TOrder>().eq("userId", tokenService.getLoginUser1().getUserid())
@@ -235,7 +236,7 @@
            tOrder.setName(byId.getName());
            tOrder.setImg(byId.getCoverImg());
            StringBuilder stringBuilder = new StringBuilder();
            if (StringUtils.hasLength(byId.getTypeIds())){
            if (StringUtils.hasLength(byId.getTypeIds())) {
                String[] split = byId.getTypeIds().split(",");
                for (String s : split) {
                    TGoodsType byId1 = goodsTypeService.getById(s);
@@ -321,7 +322,7 @@
        // 如果设置为默认地址 那么要将之前的默认地址取消掉
        List<Recipient> userId = recipientService.list(new QueryWrapper<Recipient>()
                .eq("userId", tokenService.getLoginUser1().getUserid())
                .ne("id",byId.getId()));
                .ne("id", byId.getId()));
        for (Recipient recipient1 : userId) {
            recipient1.setIsDefault(0);
            recipientService.updateById(recipient1);
@@ -339,16 +340,17 @@
            @ApiImplicitParam(value = "地址id", name = "id", dataType = "String", required = true)
    })
    public R setDefaultStudy(@RequestParam Integer id) {
        if (tokenService.getLoginUserStudy() == null) {
            return R.tokenError("登录失效");
        LoginUserParent userStudy = tokenService.getLoginUserStudy();
        if (null == userStudy) {
            return R.tokenError("登录失效!");
        }
        Recipient byId = recipientService.getById(id);
        byId.setIsDefault(1);
        recipientService.updateById(byId);
        // 如果设置为默认地址 那么要将之前的默认地址取消掉
        List<Recipient> userId = recipientService.list(new QueryWrapper<Recipient>()
                .eq("userId", tokenService.getLoginUser1().getUserid())
                .ne("id",byId.getId()));
                .eq("userId", userStudy.getUserid())
                .ne("id", byId.getId()));
        for (Recipient recipient1 : userId) {
            recipient1.setIsDefault(0);
            recipientService.updateById(recipient1);
@@ -417,18 +419,21 @@
    @ApiOperation(value = "新增收货地址/修改收货地址", tags = {"学习端-收货地址"})
    @ApiOperationSupport(order = 33)
    public R<String> addressSave(@RequestBody Recipient recipient) {
        LoginUserParent userStudy = tokenService.getLoginUserStudy();
        if (null == userStudy) {
            return R.tokenError("登录失效!");
        }
        recipient.setUserId(tokenService.getLoginUserStudy().getUserid());
        if (recipient.getIsDefault() == 1){
        if (recipient.getIsDefault() == 1) {
            // 如果设置为默认地址 那么要将之前的默认地址取消掉
            List<Recipient> userId = recipientService.list(new QueryWrapper<Recipient>()
                    .eq("userId", tokenService.getLoginUser1().getUserid()));
                    .eq("userId", userStudy.getUserid()));
            for (Recipient recipient1 : userId) {
                recipient1.setIsDefault(0);
                recipientService.updateById(recipient1);
            }
        }
        recipientService.addressSaveOrUpdate(recipient);
        return R.ok();
        return recipientService.addressSaveOrUpdate(recipient) ? R.ok() : R.fail();
    }
    /**
@@ -438,12 +443,12 @@
    @ApiOperation(value = "家长端-新增收货地址/修改收货地址", tags = {"家长端-新增收货地址/修改收货地址"})
    @ApiOperationSupport(order = 20)
    public R<String> addressSaveOrUpdateParent(@RequestBody Recipient recipient) {
        if (tokenService.getLoginUser1() == null){
        if (tokenService.getLoginUser1() == null) {
            return R.tokenError("登录失效!");
        }
        recipient.setUserId(tokenService.getLoginUser1().getUserid());
        if (recipient.getId() != null){
            if (recipient.getIsDefault() == 1){
        if (recipient.getId() != null) {
            if (recipient.getIsDefault() == 1) {
                // 如果设置为默认地址 那么要将之前的默认地址取消掉
                List<Recipient> userId = recipientService.list(new QueryWrapper<Recipient>()
                        .eq("userId", tokenService.getLoginUser1().getUserid()));
@@ -453,8 +458,8 @@
                }
            }
            recipientService.updateById(recipient);
        }else{
            if (recipient.getIsDefault() == 1){
        } else {
            if (recipient.getIsDefault() == 1) {
                // 如果设置为默认地址 那么要将之前的默认地址取消掉
                List<Recipient> userId = recipientService.list(new QueryWrapper<Recipient>()
                        .eq("userId", tokenService.getLoginUser1().getUserid()));
@@ -543,16 +548,26 @@
    @GetMapping("/updateOrderAddress")
    @ApiOperation(value = "修改订单收货地址", tags = {"学习端-收货地址"})
    @ApiOperationSupport(order = 36)
    @ApiImplicitParams({
            @ApiImplicitParam(value = "订单id", name = "orderId", dataType = "String", required = true),
            @ApiImplicitParam(value = "地址信息id", name = "recipientId", dataType = "String", required = true)
    })
    public R updateOrderAddress(@RequestParam Integer orderId, @RequestParam Integer recipientId) {
        if (tokenService.getLoginUserStudy() == null) {
            return R.tokenError("登录失效");
        }
        Recipient userId = recipientService.getById(recipientId);
        TOrder byId = orderService.getById(orderId);
        byId.setConsigneeName(userId.getAddress());
        byId.setConsigneePhone(userId.getRecipientPhone());
        byId.setConsigneeAddress(userId.getAddress());
        orderService.updateById(byId);
        Recipient recipient = recipientService.getById(recipientId);
        TOrder order = orderService.getById(orderId);
        if (null == order) {
            throw new GlobalException("订单不存在!");
        }
        if (!Constants.ONE.equals(order.getState())) {
            throw new GlobalException("订单已发货,无法修改收货地址!");
        }
        order.setConsigneeName(recipient.getAddress());
        order.setConsigneePhone(recipient.getRecipientPhone());
        order.setConsigneeAddress(recipient.getAddress());
        orderService.updateById(order);
        return R.ok();
    }
@@ -584,7 +599,7 @@
    @ApiOperation(value = "商品分类列表", tags = {"学习端-商城"})
    @ApiOperationSupport(order = 39)
    public R<List<TGoodsType>> goodTypeStudy() {
        return R.ok(goodsTypeService.lambdaQuery().eq(TGoodsType::getIsDelete, 0).eq(TGoodsType::getIsDelete, 0).list());
        return R.ok(goodsTypeService.lambdaQuery().eq(TGoodsType::getIsDelete, 0).list());
    }
    /**
@@ -601,6 +616,9 @@
    public R<GoodDetailVO> goodDetail(@RequestParam String goodId) {
        // 商品详情
        TGoods goods = goodsService.lambdaQuery().eq(TGoods::getId, goodId).one();
        if (null == goods) {
            throw new GlobalException("获取商品详情失败,商品不存在!");
        }
        // 商品分类详情
        List<TGoodsType> goodsTypes = goodsTypeService.lambdaQuery().in(TGoodsType::getId, Arrays.asList(goods.getTypeIds().split(","))).list();
        // 已兑换人数
@@ -625,6 +643,9 @@
        }
        // 商品详情
        TGoods goods = goodsService.lambdaQuery().eq(TGoods::getId, goodId).one();
        if (null == goods) {
            throw new GlobalException("获取商品详情失败,商品不存在!");
        }
        // 商品分类详情
        List<TGoodsType> goodsTypes = goodsTypeService.lambdaQuery().in(TGoodsType::getId, Arrays.asList(goods.getTypeIds().split(","))).list();
        // 已兑换人数
@@ -681,12 +702,12 @@
        Recipient recipient = recipientService.lambdaQuery()
                .eq(Recipient::getUserId, tokenService.getLoginUser1().getUserid())
                .eq(Recipient::getIsDefault, 1).one();
        if (recipient == null){
        if (recipient == null) {
            // 随便取一条地址数据
            List<Recipient> list = recipientService.lambdaQuery()
                    .eq(Recipient::getUserId, tokenService.getLoginUser1().getUserid())
                    .eq(Recipient::getIsDefault, 1).list();
            if (!list.isEmpty()){
            if (!list.isEmpty()) {
                recipient = list.get(0);
            }
        }
ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/IRecipientService.java
@@ -20,5 +20,5 @@
     * @param recipient 收货地址信息
     * @return 操作结果
     */
    String addressSaveOrUpdate(Recipient recipient);
    Boolean addressSaveOrUpdate(Recipient recipient);
}
ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/RecipientServiceImpl.java
@@ -27,7 +27,7 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String addressSaveOrUpdate(Recipient recipient) {
    public Boolean addressSaveOrUpdate(Recipient recipient) {
        boolean result;
        // 主键ID为空,新增收货地址
        if (null == recipient.getId()) {
@@ -36,6 +36,6 @@
        } else {
            result = this.updateById(recipient);
        }
        return result ? "操作成功!" : "操作失败!";
        return result;
    }
}
ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/RegionServiceImpl.java
@@ -46,6 +46,12 @@
                region.getChildren().add(e);
            }
        });
        for (Region region : treeData) {
            List<Region> children = region.getChildren();
            for (Region child : children) {
                child.setChildren(new ArrayList<>());
            }
        }
        return treeData;
    }
ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/TGoodsServiceImpl.java
@@ -4,6 +4,7 @@
import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.constant.RedisConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.exception.GlobalException;
import com.ruoyi.common.security.service.TokenService;
import com.ruoyi.goods.domain.Recipient;
import com.ruoyi.goods.domain.TGoods;
@@ -16,7 +17,7 @@
import com.ruoyi.goods.vo.TGoodsVO;
import com.ruoyi.study.api.domain.TUser;
import com.ruoyi.study.api.feignClient.StudyClient;
import com.ruoyi.system.api.model.LoginUserParent;
import com.ruoyi.study.api.vo.UserPersonalCenterVO;
import org.redisson.api.RSemaphore;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;
@@ -75,22 +76,26 @@
            return R.exchangeError("商品不存在,请稍后重试!");
        }
        // 校验用户积分是否足够兑换
        TUser user = studyClient.userInfo().getData();
        LoginUserParent loginUser1 = tokenService.getLoginUser1();
        if (user == null){
            user = studyClient.getUserById(loginUser1.getUserid()).getData();
        UserPersonalCenterVO userPersonalCenter = studyClient.userInfo().getData();
        if (null == userPersonalCenter) {
            throw new GlobalException("用户信息获取失败!");
        }
        TUser user = userPersonalCenter.getUser();
        int needIntegral = good.getIntegral() * number;
        if (user.getIntegral() < needIntegral) {
            return R.exchangeError("兑换失败,当前剩余积分不足!");
        }
        // 检查用户兑换数量是否超过单用户最大兑换数量
        List<TOrder> orderList = orderService.lambdaQuery().eq(TOrder::getUserId, user.getId()).eq(TOrder::getGoodsId, goodId).list();
        List<TOrder> orderList = orderService.lambdaQuery().eq(TOrder::getUserId, user.getId())
                .eq(TOrder::getGoodsId, goodId).list();
        // 该商品订单为空、订单数量未超过商品的单个用户兑换上限数量时,可以进行兑换
        int totalNumber = orderList.stream().map(TOrder::getCount).collect(Collectors.toList()).stream().mapToInt(Integer::intValue).sum();
        boolean canExchange = orderList.isEmpty() || null == good.getUserCount() || (totalNumber + number) <= good.getUserCount();
        int totalNumber = orderList.stream().map(TOrder::getCount).collect(Collectors.toList())
                .stream().mapToInt(Integer::intValue).sum();
        boolean canExchange = orderList.isEmpty() || null == good.getUserCount() ||
                (totalNumber + number) <= good.getUserCount();
        if (!canExchange) {
            return R.exchangeError("兑换失败,当前兑换数量已超过最大兑换数量,剩余兑换数量为: " + (good.getUserCount() - totalNumber) + "!");
            return R.exchangeError("兑换失败,当前兑换数量已超过最大兑换数量,剩余兑换数量为: " +
                    (good.getUserCount() - totalNumber) + "!");
        }
        // redisson分布式锁,防止超卖
        String key = String.format(RedisConstants.GOOD_STOCK, good.getId());
@@ -111,7 +116,8 @@
        // 扣除用户积分
        result = result && studyClient.exchangeIntegral(needIntegral, Constants.BURDEN).getData();
        // 扣除库存
        result = result && this.lambdaUpdate().set(TGoods::getSurplus, good.getSurplus() - number).eq(TGoods::getId, good.getId()).update();
        result = result && this.lambdaUpdate().set(TGoods::getSurplus, good.getSurplus() - number)
                .eq(TGoods::getId, good.getId()).update();
        if (!result) {
            semaphore.release(number);
            return R.exchangeError("商品兑换失败!");
@@ -129,7 +135,7 @@
            return R.exchangeError("商品不存在,请稍后重试!");
        }
        // 校验用户积分是否足够兑换
        if (tokenService.getLoginUser1() == null){
        if (tokenService.getLoginUser1() == null) {
            return R.tokenError("登录失效");
        }
        TUser user = studyClient.getUserById(tokenService.getLoginUser1().getUserid()).getData();
@@ -188,6 +194,7 @@
        order.setDisabled(Boolean.FALSE);
        return order;
    }
    private TOrder orderInfo1(GoodExchangeDTO goodExchange, Recipient recipient, Integer number, Integer goodId, int needIntegral) {
        TOrder order = new TOrder();
        order.setOrderNumber(goodExchange.getOrderNumber());
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/config/DataUpdateHandlerConfig.java
@@ -3,6 +3,7 @@
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.ruoyi.common.security.service.TokenService;
import com.ruoyi.system.api.model.LoginUser;
import com.ruoyi.system.api.model.LoginUserParent;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.beans.factory.annotation.Autowired;
@@ -30,8 +31,6 @@
    /**
     * 新增数据执行
     *
     * @param metaObject
     */
    @Override
    public void insertFill(MetaObject metaObject) {
@@ -61,15 +60,13 @@
    /**
     * 修改数据执行
     *
     * @param metaObject
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        //  获取登录信息
        LoginUser loginUser = tokenService.getLoginUser();
        if (loginUser != null) {
            String userName = loginUser.getUsername();
        LoginUserParent userStudy = tokenService.getLoginUserStudy();
        if (userStudy != null) {
            String userName = userStudy.getName();
            if (StringUtils.hasLength(userName)) {
                this.setFieldValByName("createBy", userName, metaObject);
                this.setFieldValByName("createTime", new Date(), metaObject);
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TStudyController.java
@@ -2,16 +2,17 @@
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.exception.GlobalException;
import com.ruoyi.common.core.web.page.PageInfo;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.common.security.service.TokenService;
import com.ruoyi.goods.api.feignClient.GoodsClient;
import com.ruoyi.goods.api.model.TGoodsVO;
import com.ruoyi.management.api.feignClient.ManagementClient;
import com.ruoyi.management.api.model.TSysSet;
import com.ruoyi.study.domain.*;
import com.ruoyi.study.dto.*;
import com.ruoyi.study.service.*;
@@ -70,13 +71,13 @@
    @Resource
    private ITIntegralRecordService integralRecordService;
    @Resource
    private RedisService redisService;
    @Resource
    private ITUserService userService;
    @Resource
    private TokenService tokenService;
    @Resource
    private ITSubjectRecordService subjectRecordService;
    @Resource
    private IUserStudyRecordService studyRecordService;
    @Resource
    private ManagementClient managementClient;
@@ -143,7 +144,7 @@
                List<TSubject> list1 = subjectService.list(wrapper);
                List<TSubject> tSubjects = new ArrayList<>();
                for (TSubject tSubject : list1) {
                    if (!tSubject.getError().isEmpty()){
                    if (!tSubject.getError().isEmpty()) {
                        tSubjects.add(tSubject);
                    }
                }
@@ -667,24 +668,40 @@
     */
    @GetMapping("/goodRecommend")
    @ApiOperation(value = "可兑换商品推荐", tags = {"学习端-首页"})
    public R<List<TGoodsVO>> studySchedule() {
    public R<List<TGoodsVO>> goodRecommend() {
        return R.ok(goodsClient.goodRecommend().getData());
    }
    /**
     * 获取正确及错误提示音效
     */
    @GetMapping("/promptVoice")
    @ApiOperation(value = "获取正确及错误提示音效", tags = {"学习端-首页"})
    public R<TSysSet> promptVoice() {
        return R.ok(managementClient.promptVoice().getData());
    }
    /**
     * 首次页面加载时调用,获取学习进度及学习时长等信息
     *
     * @param week 周目
     * @param day  所属day
     */
    @GetMapping("/studySchedule")
    @ApiOperation(value = "获取用户学习进度", tags = {"学习端-首页"})
    @ApiImplicitParams({
            @ApiImplicitParam(value = "周目", name = "week", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "所属day", name = "day", dataType = "Integer", required = true)
            @ApiImplicitParam(value = "周目", name = "week", dataType = "Integer", required = true)
    })
    public R<TUserStudy> studySchedule(@RequestParam Integer week, @RequestParam Integer day) {
        TUserStudy result = studyService.studySchedule(String.valueOf(tokenService.getLoginUserStudy().getUserid()), week);
    public R<TUserStudy> studySchedule(@RequestParam Integer week) {
        LoginUserParent loginStudy = tokenService.getLoginUserStudy();
        if (null == loginStudy) {
            return R.tokenError("登录失效!");
        }
        TUserStudy result = studyService.studySchedule(String.valueOf(loginStudy.getUserid()), week);
        if (null != result) {
            // 计算当前周 day 1-5的总进度
            int computeSchedule = studyService.computeSchedule(result, week);
            result.setComputeSchedule(computeSchedule);
        }
        return R.ok(result);
    }
@@ -715,12 +732,39 @@
    @ApiOperation(value = "获取题组学习进度信息", tags = {"学习端-题目"})
    @ApiImplicitParams({
            @ApiImplicitParam(value = "周目", name = "week", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "所属day", name = "day", dataType = "Integer", required = true)
            @ApiImplicitParam(value = "所属day", name = "day", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "类型(1:听音选图,2:看图选音,3:归纳排除,4:有问有答,5:音图相配)", name = "type", dataType = "Integer", required = true)
    })
    public R<TSubjectRecord> teamSchedule(@RequestParam Integer week, @RequestParam Integer day) {
        TSubjectRecord subjectRecord = subjectRecordService.lambdaQuery().eq(TSubjectRecord::getWeek, week).eq(TSubjectRecord::getDay, day)
                .eq(TSubjectRecord::getUserId, tokenService.getLoginUserStudy().getUserid()).eq(TSubjectRecord::getDisabled, 0).one();
        return R.ok(subjectRecord);
    public R<SubjectRecordResultVO> teamSchedule(@RequestParam Integer week, @RequestParam Integer day,
                                                 @RequestParam Integer type) {
        LoginUserParent loginStudy = tokenService.getLoginUserStudy();
        if (null == loginStudy) {
            return R.tokenError("登录失效!");
        }
        TSubjectRecord subjectRecord = subjectRecordService.lambdaQuery().eq(TSubjectRecord::getWeek, week)
                .eq(TSubjectRecord::getDay, day)
                .eq(TSubjectRecord::getType, type)
                .eq(TSubjectRecord::getUserId, loginStudy.getUserid())
                .eq(TSubjectRecord::getDisabled, 0).one();
        // 返回结果
        SubjectRecordResultVO result;
        SubjectRecordResultVO data = subjectRecordService.recordResult(subjectRecord, loginStudy.getUserid());
        if (null != subjectRecord) {
            subjectRecordService.lambdaUpdate().set(TSubjectRecord::getDisabled, 1)
                    .eq(TSubjectRecord::getId, subjectRecord.getId()).update();
            // 题组id
            List<Integer> teamIds = Arrays.stream(subjectRecord.getBeforeSubject().split(",")).map(Integer::parseInt)
                    .collect(Collectors.toList());
            // 题目id
            List<Integer> topicIds = Arrays.stream(subjectRecord.getCompleteSubject().split(",")).map(Integer::parseInt)
                    .collect(Collectors.toList());
            result = new SubjectRecordResultVO(teamIds, topicIds, subjectRecord.getAnswerNumber(), subjectRecord.getCorrectNumber());
        } else {
            result = new SubjectRecordResultVO();
        }
        subjectRecordService.lambdaUpdate().set(TSubjectRecord::getDisabled, 0)
                .eq(TSubjectRecord::getUserId, loginStudy.getUserid()).update();
        return R.ok(result);
    }
    /**
@@ -728,9 +772,43 @@
     */
    @PostMapping("/exitLearning")
    @ApiOperation(value = "退出学习(记录学习进度等信息)", tags = {"学习端-题目"})
    public R<Boolean> exitLearning(@RequestBody TSubjectRecord subjectRecord) {
        // 学习时长处理
        return R.ok(subjectRecordService.updateById(subjectRecord));
    public R<Boolean> exitLearning(@RequestBody ExitLearnVO exitLearn) {
        LoginUserParent loginStudy = tokenService.getLoginUserStudy();
        if (null == loginStudy) {
            return R.tokenError("登录失效!");
        }
        Integer userid = loginStudy.getUserid();
        // 判断当前week和day是否已完成学习
        TUserStudy userStudy = userStudyService.lambdaQuery().eq(TUserStudy::getUserId, userid)
                .eq(TUserStudy::getDisabled, 0).one();
        if (null == userStudy) {
            throw new GlobalException("登录用户学习记录不存在!");
        }
        if (userStudy.getWeek().equals(exitLearn.getWeek()) && userStudy.getDay().equals(exitLearn.getDay())) {
            // 计算完成率
            int completionRate = exitLearn.getTopicIds().split(",").length * 5;
            Integer type = exitLearn.getType();
            // 更新用户学习完成率
            LambdaUpdateChainWrapper<TUserStudy> wrapper = userStudyService.lambdaUpdate();
            if (Constants.ONE.equals(type) && userStudy.getListen() < completionRate) {
                // 听音选图
                wrapper.set(TUserStudy::getListen, completionRate);
            } else if (Constants.TWO.equals(type) && userStudy.getLook() < completionRate) {
                // 看图选音
                wrapper.set(TUserStudy::getLook, completionRate);
            } else if (Constants.THREE.equals(type) && userStudy.getInduction() < completionRate) {
                // 归纳排除
                wrapper.set(TUserStudy::getInduction, completionRate);
            } else if (Constants.FOUR.equals(type) && userStudy.getAnswer() < completionRate) {
                // 有问有答
                wrapper.set(TUserStudy::getAnswer, completionRate);
            } else if (Constants.FIVE.equals(type) && userStudy.getPair() < completionRate) {
                // 音图相配
                wrapper.set(TUserStudy::getPair, completionRate);
            }
            wrapper.eq(TUserStudy::getUserId, userid).update();
        }
        return R.ok(subjectRecordService.exitLearning(exitLearn, userid));
    }
    /**
@@ -746,7 +824,8 @@
            @ApiImplicitParam(value = "周目", name = "week", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "所属day", name = "day", dataType = "Integer", required = true)
    })
    public R<StudyListenResultVO> listenSelectPicture(@RequestParam Integer quarter, @RequestParam Integer week, @RequestParam Integer day) {
    public R<StudyListenResultVO> listenSelectPicture(@RequestParam Integer quarter, @RequestParam Integer week,
                                                      @RequestParam Integer day) {
        // 判断当前登录用户是否为 会员
        Boolean isVip = userService.isVip();
        // 非会员只能查看非会员题目,会员可以查看所有题目
@@ -776,7 +855,8 @@
            @ApiImplicitParam(value = "周目", name = "week", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "所属day", name = "day", dataType = "Integer", required = true)
    })
    public R<StudyLookResultVO> pictureSelectVoice(@RequestParam Integer quarter, @RequestParam Integer week, @RequestParam Integer day) {
    public R<StudyLookResultVO> pictureSelectVoice(@RequestParam Integer quarter, @RequestParam Integer week,
                                                   @RequestParam Integer day) {
        // 判断当前登录用户是否为 会员
        Boolean isVip = userService.isVip();
        // 非会员只能查看非会员题目,会员可以查看所有题目
@@ -806,7 +886,8 @@
            @ApiImplicitParam(value = "周目", name = "week", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "所属day", name = "day", dataType = "Integer", required = true)
    })
    public R<StudyInductionResultVO> induceExclude(@RequestParam Integer quarter, @RequestParam Integer week, @RequestParam Integer day) {
    public R<StudyInductionResultVO> induceExclude(@RequestParam Integer quarter, @RequestParam Integer week,
                                                   @RequestParam Integer day) {
        // 判断当前登录用户是否为 会员
        Boolean isVip = userService.isVip();
        // 非会员只能查看非会员题目,会员可以查看所有题目
@@ -836,7 +917,8 @@
            @ApiImplicitParam(value = "周目", name = "week", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "所属day", name = "day", dataType = "Integer", required = true)
    })
    public R<StudyAnswerResultVO> questionsAndAnswers(@RequestParam Integer quarter, @RequestParam Integer week, @RequestParam Integer day) {
    public R<StudyAnswerResultVO> questionsAndAnswers(@RequestParam Integer quarter, @RequestParam Integer week,
                                                      @RequestParam Integer day) {
        // 判断当前登录用户是否为 会员
        Boolean isVip = userService.isVip();
        // 非会员只能查看非会员题目,会员可以查看所有题目
@@ -866,7 +948,8 @@
            @ApiImplicitParam(value = "周目", name = "week", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "所属day", name = "day", dataType = "Integer", required = true)
    })
    public R<StudyPairResultVO> pictureMateVoice(@RequestParam Integer quarter, @RequestParam Integer week, @RequestParam Integer day) {
    public R<StudyPairResultVO> pictureMateVoice(@RequestParam Integer quarter, @RequestParam Integer week,
                                                 @RequestParam Integer day) {
        // 判断当前登录用户是否为 会员
        Boolean isVip = userService.isVip();
        // 非会员只能查看非会员题目,会员可以查看所有题目
@@ -891,50 +974,59 @@
    @PostMapping("/completeLearning")
    @ApiOperation(value = "完成学习", tags = {"学习端-听-自主学习"})
    public R<Boolean> completeLearning(@RequestBody CompleteStudyDTO completeStudy) {
        LoginUserParent userStudy = tokenService.getLoginUserStudy();
        if (null == userStudy) {
            return R.tokenError("登录失效!");
        }
        // 登录用户id
        Integer userId = tokenService.getLoginUserStudy().getUserid();
        Integer userId = userStudy.getUserid();
        // 判断是否已完成该题组
        boolean update = true;
        if (completeStudy.getIsComplete()) {
            List<Integer> studyIds = completeStudy.getStudyIds();
            Integer type = completeStudy.getType();
            int sum;
            if (Constants.ONE.equals(type)) {
                List<TStudyListen> studyListens = studyListenService.lambdaQuery().in(TStudyListen::getId, studyIds)
                        .eq(TStudyListen::getDisabled, 0).list();
                sum = studyListens.stream().mapToInt(TStudyListen::getIntegral).sum();
            } else if (Constants.TWO.equals(type)) {
                List<TStudyLook> studyListens = studyLookService.lambdaQuery().in(TStudyLook::getId, studyIds)
                        .eq(TStudyLook::getDisabled, 0).list();
                sum = studyListens.stream().mapToInt(TStudyLook::getIntegral).sum();
            } else if (Constants.THREE.equals(type)) {
                List<TStudyInduction> studyListens = studyInductionService.lambdaQuery().in(TStudyInduction::getId, studyIds)
                        .eq(TStudyInduction::getDisabled, 0).list();
                sum = studyListens.stream().mapToInt(TStudyInduction::getIntegral).sum();
            } else if (Constants.FOUR.equals(type)) {
                List<TStudyAnswer> studyListens = studyAnswerService.lambdaQuery().in(TStudyAnswer::getId, studyIds)
                        .eq(TStudyAnswer::getDisabled, 0).list();
                sum = studyListens.stream().mapToInt(TStudyAnswer::getIntegral).sum();
            } else if (Constants.FIVE.equals(type)) {
                List<TStudyPair> studyListens = studyPairService.lambdaQuery().in(TStudyPair::getId, studyIds)
                        .eq(TStudyPair::getDisabled, 0).list();
                sum = studyListens.stream().mapToInt(TStudyPair::getIntegral).sum();
            } else {
                return R.fail("题目信息异常!");
            }
        List<String> studyIds = Arrays.stream(completeStudy.getStudyIds().split(","))
                .collect(Collectors.toList());
        Integer type = completeStudy.getType();
        // 可获取的总积分数量以及获取用户该学习已获取的积分数量,并计算本次可获取的剩余积分数量
        int sum = studyService.computeTotalIntegral(studyIds, type, completeStudy.getAccuracy());
        // 用户已获取的积分数量
        int obtainedIntegral;
        List<TUserStudyRecord> list = studyRecordService.lambdaQuery()
                .eq(TUserStudyRecord::getQuarter, completeStudy.getQuarter())
                .eq(TUserStudyRecord::getWeek, completeStudy.getWeek())
                .eq(TUserStudyRecord::getDay, completeStudy.getDay())
                .eq(TUserStudyRecord::getType, 0)
                .eq(TUserStudyRecord::getUserId, userId).list();
        if (list.isEmpty()) {
            obtainedIntegral = 0;
        } else {
            obtainedIntegral = list.stream().map(TUserStudyRecord::getObtainedIntegral)
                    .mapToInt(Integer::intValue).sum();
        }
        // 计算本次可获取积分数量
        if (sum > obtainedIntegral) {
            int integral = sum - obtainedIntegral;
            // 获取user详细信息,改变积分
            TUser user = userService.getById(userId);
            user.setIntegral(user.getIntegral() + sum);
            update = userService.updateById(user);
            int i = user.getIntegral() + integral;
            update = userService.lambdaUpdate().eq(TUser::getId, userId).set(TUser::getIntegral, i).update();
            // 生成积分明细记录
            TIntegralRecord integralRecord = new TIntegralRecord();
            integralRecord.setIntegral(String.valueOf(sum));
            integralRecord.setIntegral(String.valueOf(integral));
            integralRecord.setMethod(Constants.COMPLETE_LEARNING);
            integralRecord.setUserId(userId);
            update = update && integralRecordService.save(integralRecord);
            // 生成学习完成记录
            TUserStudyRecord record = new TUserStudyRecord();
            record.setUserId(userId);
            record.setQuarter(completeStudy.getQuarter());
            record.setWeek(completeStudy.getWeek());
            record.setDay(completeStudy.getDay());
            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();
        List<TStudy> studyList = studyService.lambdaQuery().eq(TStudy::getDisabled, 0)
                .orderByAsc(TStudy::getWeek).list();
        if (studyList.isEmpty()) {
            throw new GlobalException("学习配置列表未配置或数据失效!");
        }
@@ -956,7 +1048,12 @@
            @ApiImplicitParam(value = "难度(0入门、1中级、2困难)", name = "difficulty", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "所属周目", name = "week", dataType = "Integer", required = true)
    })
    public R<StudyGamerResultVO> gameHearing(@RequestParam Integer quarter, @RequestParam Integer difficulty, @RequestParam Integer week) {
    public R<StudyGameResultVO> gameHearing(@RequestParam Integer quarter, @RequestParam Integer difficulty,
                                            @RequestParam Integer week) {
        Integer[] array = {0, 1, 2};
        if (!Arrays.stream(array).collect(Collectors.toList()).contains(difficulty)) {
            throw new GlobalException("请选择符合规则的游戏难度!");
        }
        TGame game = gameService.gameHearing(quarter, week);
        if (null == game) {
            throw new GlobalException("当前季度该周目暂无配置游戏数据!");
@@ -977,21 +1074,9 @@
            throw new GlobalException("当前周目下day1 - day5题目不足!");
        }
        // 根据游戏设置数量获取图片及语音
        List<String> subjectData = new ArrayList<>();
        Random random = new Random();
        // 获取列表大小
        int dataSize = newSubjectId.size();
        // 生成随机索引并获取数据
        for (int i = 0; i < game.getCount(); i++) {
            // 生成随机索引
            int randomIndex = random.nextInt(dataSize);
            // 获取对应的数据并加入结果列表
            subjectData.add(newSubjectId.get(randomIndex));
            newSubjectId.remove(randomIndex);
            dataSize = newSubjectId.size();
        }
        List<String> subjectData = getData(game, newSubjectId);
        List<TSubject> subjectList = getSubjectList(subjectData);
        return R.ok(new StudyGamerResultVO(game, subjectList));
        return R.ok(new StudyGameResultVO(game, subjectList));
    }
    /**
@@ -1006,12 +1091,27 @@
            @ApiImplicitParam(value = "季度", name = "quarter", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "所属周目", name = "week", dataType = "Integer", required = true)
    })
    public R<StudyGamerResultVO> gameMemory(@RequestParam Integer quarter, @RequestParam Integer week) {
    public R<StudyGameMemoryVO> gameMemory(@RequestParam Integer quarter, @RequestParam Integer week) {
        TGame game = gameService.gameHearing(quarter, week);
        if (null == game) {
            throw new GlobalException("当前季度该周目暂无配置游戏数据!");
        }
        List<String> subjectId = getSubjectId(week);
        List<String> subjectData = getSubjectData(game, subjectId);
        List<TSubject> subjectList = getSubjectList(subjectData);
        // 返回数据
        List<GameMemoryPhotoVO> photoList = new ArrayList<>();
        List<GameMemoryVoiceVO> voiceList = new ArrayList<>();
        for (TSubject tSubject : subjectList) {
            photoList.add(new GameMemoryPhotoVO(tSubject.getId(), tSubject.getImg()));
            voiceList.add(new GameMemoryVoiceVO(tSubject.getId(), tSubject.getCorrect()));
        }
        // 框架记忆数量翻倍,前端需要根据数量画格子
        game.setAnswerCount(game.getAnswerCount() * 2);
        return R.ok(new StudyGameMemoryVO(game, photoList, voiceList));
    }
    private List<String> getSubjectData(TGame game, List<String> subjectId) {
        List<String> newSubjectId = subjectId.stream().map(data -> {
            if (data.startsWith(Constants.REDUCE)) {
                data = data.replace(Constants.REDUCE, Constants.EMPTY_STR);
@@ -1023,6 +1123,10 @@
            throw new GlobalException("当前周目下day1 - day5题目不足!");
        }
        // 根据游戏设置数量获取图片及语音
        return getData(game, newSubjectId);
    }
    private List<String> getData(TGame game, List<String> newSubjectId) {
        List<String> subjectData = new ArrayList<>();
        Random random = new Random();
        // 获取列表大小
@@ -1036,15 +1140,7 @@
            newSubjectId.remove(randomIndex);
            dataSize = newSubjectId.size();
        }
        List<TSubject> subjectList = getSubjectList(subjectData);
        // 格子翻倍,前端需要做连连看
        List<TSubject> resultList = new ArrayList<>();
        for (int i = 0; i < Constants.TWO; i++) {
            resultList.addAll(subjectList);
        }
        // 框架记忆数量翻倍,前端需要根据数量画格子
        game.setAnswerCount(game.getAnswerCount() * 2);
        return R.ok(new StudyGamerResultVO(game, resultList));
        return subjectData;
    }
    private List<TSubject> getSubjectList(List<String> subjectData) {
@@ -1069,12 +1165,16 @@
    @PostMapping("/gameAchievement")
    @ApiOperation(value = "完成游戏-记录游戏测试成绩", tags = {"学习端-听-自主游戏"})
    public R<Boolean> gameAchievement(@RequestBody CompleteGameDTO completeStudy) {
        LoginUserParent userStudy = tokenService.getLoginUserStudy();
        if (null == userStudy) {
            return R.tokenError("登录失效!");
        }
        /*
         * 游戏测试需要根据正确率计算本次测试可获得积分
         * 并且需要判断如果该游戏用户已获取一部分积分,再次测试后正确率增长,只能获取高于上次正确率的部分积分
         * 例如:游戏配置的积分是100,他的正确率是50%那么拿50分,下次他再玩这个游戏 正确率是60% 那么他该获得60分 但是上次已经拿了50 所以这次就只给他加10积分
         */
        Integer userid = tokenService.getLoginUserStudy().getUserid();
        Integer userid = userStudy.getUserid();
        TGame game = gameService.lambdaQuery().eq(TGame::getId, completeStudy.getGameId()).eq(TGame::getDisabled, 0).one();
        if (null == game) {
            throw new GlobalException("游戏信息异常!");
@@ -1092,7 +1192,7 @@
        } else {
            throw new GlobalException("该次游戏积分计算异常!");
        }
        int gameAvailableIntegral = integral * (completeStudy.getAccuracy() / 100);
        int gameAvailableIntegral = (int) (integral * ((double) completeStudy.getAccuracy() / 100));
        Integer availableIntegral = gameService.countIntegral(userid, game, completeStudy, gameAvailableIntegral, integralRecordList);
        // 游戏测试记录
        Boolean add = gameRecordService.add(completeStudy);
@@ -1150,15 +1250,14 @@
    })
    public R<StudyStoryListenResultVO> lookPictureDbu(@RequestParam Integer quarter, @RequestParam Integer week) {
        // 看图配音信息
        TStoryListen listen = gettStoryListen(quarter, week);
        List<String> list = Arrays.asList(listen.getLookStory().split(","));
        List<TStory> subjectList;
        if (!list.isEmpty()) {
            subjectList = storyService.lambdaQuery().in(TStory::getId, list).eq(TStory::getDisabled, 0).list();
        } else {
            subjectList = new ArrayList<>();
        }
        return R.ok(new StudyStoryListenResultVO(listen, subjectList));
        TStoryListen storyListen = storyListenService.storyDetail(quarter, week);
        // 题组信息
        StudyStoryVO studyStory = new StudyStoryVO();
        studyStory.setId(storyListen.getId());
        studyStory.setIntegral(storyListen.getLookIntegral());
        // 故事语音及图片信息
        List<TStory> list = storyService.lookPictureDbu(storyListen, 0);
        return R.ok(new StudyStoryListenResultVO(studyStory, list));
    }
    /**
@@ -1173,34 +1272,15 @@
            @ApiImplicitParam(value = "所属周目", name = "week", dataType = "Integer", required = true)
    })
    public R<StudyStoryListenResultVO> frameworkMemory(@RequestParam Integer quarter, @RequestParam Integer week) {
        TStoryListen listen = gettStoryListen(quarter, week);
        // 获取对应图片语音
        List<String> list = Arrays.asList(listen.getStory().split(","));
        List<TStory> subjectList;
        if (!list.isEmpty()) {
            subjectList = storyService.lambdaQuery().in(TStory::getId, list).eq(TStory::getDisabled, 0).list();
        } else {
            subjectList = new ArrayList<>();
        }
        return R.ok(new StudyStoryListenResultVO(listen, subjectList));
    }
    private TStoryListen gettStoryListen(Integer quarter, Integer week) {
        // 看图配音信息
        List<TStoryListen> storyListenList = storyListenService.storyDetail(quarter, week);
        if (storyListenList.isEmpty()) {
            throw new GlobalException("当前季度该周目下未配置故事信息!");
        }
        // 获取对应图片语音
        TStoryListen listen;
        if (storyListenList.size() == Constants.ONE) {
            listen = storyListenList.get(Constants.ZERO);
        } else {
            // 随机获取一组题
            Random rand = new Random();
            listen = storyListenList.get(rand.nextInt(storyListenList.size()));
        }
        return listen;
        TStoryListen storyListen = storyListenService.storyDetail(quarter, week);
        // 题组信息
        StudyStoryVO studyStory = new StudyStoryVO();
        studyStory.setId(storyListen.getId());
        studyStory.setIntegral(storyListen.getIntegral());
        // 故事语音及图片信息
        List<TStory> list = storyService.lookPictureDbu(storyListen, 1);
        return R.ok(new StudyStoryListenResultVO(studyStory, list));
    }
    /**
@@ -1209,27 +1289,63 @@
    @GetMapping("/completeStory")
    @ApiOperation(value = "完成故事学习", tags = {"学习端-听-自主故事"})
    @ApiImplicitParams({
            @ApiImplicitParam(value = "积分数量", name = "integral", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "故事id", name = "storyId", dataType = "Integer", required = true)
            @ApiImplicitParam(value = "故事id", name = "storyId", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "类型(1:看图配音;2:超级记忆)", name = "type", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "正确率", name = "accuracy", dataType = "Integer")
    })
    public R<Boolean> completeStory(@RequestParam Integer integral, @RequestParam Integer storyId) {
        TStoryListen storyListen = storyListenService.lambdaQuery().eq(TStoryListen::getId, storyId).eq(TStoryListen::getDisabled, 0).one();
    public R<Boolean> completeStory(@RequestParam Integer storyId, @RequestParam Integer type, Integer accuracy) {
        TStoryListen storyListen = storyListenService.lambdaQuery().eq(TStoryListen::getId, storyId)
                .eq(TStoryListen::getDisabled, 0).one();
        if (null == storyListen) {
            throw new GlobalException("当前故事学习失败,故事信息异常,请重试!");
        }
        LoginUserParent userStudy = tokenService.getLoginUserStudy();
        if (null == userStudy) {
            return R.tokenError("登录失效!");
        }
        // 用户信息
        Integer userId = tokenService.getLoginUserStudy().getUserid();
        // 故事只有首次才能获取积分
        TIntegralRecord integralRecord = integralRecordService.lambdaQuery().eq(TIntegralRecord::getUserId, userId)
                .eq(TIntegralRecord::getStoryId, storyId).eq(TIntegralRecord::getDisabled, 0).one();
        Integer userId = userStudy.getUserid();
        Boolean result = true;
        if (null == integralRecord) {
            // 添加积分明细记录
            result = integralRecordService.add(String.valueOf(integral), Constants.COMPLETE_STORY, null, storyId);
            TUser user = userService.lambdaQuery().eq(TUser::getId, userId).one();
            // 添加积分
            user.setIntegral(user.getIntegral() + integral);
            result = result && userService.updateById(user);
        if (Constants.ONE.equals(type)) {
            if (null == accuracy) {
                throw new GlobalException("自主故事-看图配音正确率异常!");
            }
            // 看图配音模式,也需要根据游戏正确率计算积分
            int integral = storyListen.getLookIntegral() * (accuracy / 100);
            int obtainedIntegral;
            List<TUserStudyRecord> list = studyRecordService.lambdaQuery()
                    .eq(TUserStudyRecord::getStoryId, storyId)
                    .eq(TUserStudyRecord::getType, 1)
                    .eq(TUserStudyRecord::getUserId, userId).list();
            if (list.isEmpty()) {
                obtainedIntegral = 0;
            } else {
                obtainedIntegral = list.stream().map(TUserStudyRecord::getObtainedIntegral).mapToInt(Integer::intValue).sum();
            }
            // 可获得积分计算
            if (integral > obtainedIntegral) {
                TUserStudyRecord data = new TUserStudyRecord();
                data.setUserId(userId);
                data.setObtainedIntegral(integral - obtainedIntegral);
                data.setType(Constants.ONE);
                data.setStoryId(storyId);
                result = studyRecordService.save(data);
            }
        } else {
            // 超级记忆只有首次才能获取积分
            TIntegralRecord integralRecord = integralRecordService.lambdaQuery()
                    .eq(TIntegralRecord::getUserId, userId)
                    .eq(TIntegralRecord::getStoryId, storyId)
                    .eq(TIntegralRecord::getDisabled, 0).one();
            if (null == integralRecord) {
                // 添加积分明细记录
                result = integralRecordService.add(String.valueOf(storyListen.getIntegral()),
                        Constants.COMPLETE_STORY, null, storyId);
                TUser user = userService.lambdaQuery().eq(TUser::getId, userId).one();
                // 添加积分
                user.setIntegral(user.getIntegral() + storyListen.getIntegral());
                result = result && userService.updateById(user);
            }
        }
        return R.ok(result);
    }
@@ -1237,8 +1353,11 @@
    @GetMapping("/studyRecord")
    @ApiOperation(value = "个人中心-学习记录", tags = {"学习端-个人中心"})
    public R<StudyRecordResultVO> studyRecord() {
        Integer userId = tokenService.getLoginUserStudy().getUserid();
        LoginUserParent userStudy = tokenService.getLoginUserStudy();
        if (null == userStudy) {
            return R.tokenError("登录失效!");
        }
        Integer userId = userStudy.getUserid();
        // 学习记录
        TUserStudy studyRecord = userStudyService.lambdaQuery().eq(TUserStudy::getUserId, userId)
                .eq(TUserStudy::getDisabled, 0).one();
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TUserController.java
@@ -3,6 +3,7 @@
import com.alipay.api.AlipayApiException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.constant.RedisConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.exception.GlobalException;
@@ -424,6 +425,7 @@
        }
        return R.ok(data);
    }
    @PostMapping("/useGuideGetInfo")
    @ApiOperation(value = "查看详情", tags = {"家长端-使用指南"})
    public R useGuideGetInfo(Integer id) {
@@ -432,7 +434,7 @@
        useGuideQuery.setPageSize(300);
        PageInfo<TUseGuide> data = managementClient.useGuide1(useGuideQuery).getData();
        for (TUseGuide record : data.getRecords()) {
            if (record.getId() == id){
            if (record.getId() == id) {
                return R.ok(record.getAnswer());
            }
        }
@@ -508,6 +510,19 @@
    public R<Map<String, Object>> studyLogin(@RequestBody RegisterPhoneRequest phoneRequest) {
        String phone = phoneRequest.getPhone();
        String phoneCode = phoneRequest.getPhoneCode();
        // 验证码校验
        Object redisPhoneCode = redisService.getCacheObject(RedisConstants.PHONE_CODE + phone);
        if (null == redisPhoneCode) {
            return R.errorCode("登录失败,验证码无效!");
        } else {
            // redis 验证码的value 为 code:时间戳
            String rCodeAndTime = String.valueOf(redisPhoneCode);
            String rCode = rCodeAndTime.split(":")[0];
            if (!rCode.equalsIgnoreCase(phoneCode)) {
                return R.errorCode("登录失败,验证码无效!");
            }
        }
        // 获取手机号所注册用户信息
        TUser user = userService.getOne(new QueryWrapper<TUser>()
                .ne("state", 3)
                .eq("phone", phone));
@@ -516,26 +531,8 @@
                return R.freeze("登录失败,您的账号已被冻结!");
            }
        } else {
            if (!phoneCode.equals("123456")) {
                // 手机验证码校验
                Object redisPhoneCode = redisService.getCacheObject(RedisConstants.PHONE_CODE + phone);
                if (null == redisPhoneCode) {
                    return R.errorCode("登录失败,验证码无效!");
                } else {
                    // redis 验证码的value 为 code:时间戳
                    String rCodeAndTime = String.valueOf(redisPhoneCode);
                    String rCode = rCodeAndTime.split(":")[0];
                    if (!rCode.equalsIgnoreCase(phoneCode)) {
                        return R.errorCode("登录失败,验证码无效!");
                    } else {
                        user = getUser(phone);
                        userService.save(user);
                    }
                }
            } else {
                user = getUser(phone);
                userService.save(user);
            }
            user = getUser(phone);
            userService.save(user);
        }
        // 生成登录用户信息
        LoginUserParent loginUserParent = new LoginUserParent();
@@ -544,8 +541,27 @@
        loginUserParent.setPhone(user.getPhone());
        loginUserParent.setLoginTime(System.currentTimeMillis());
        HashMap<String, Object> map = new HashMap<>();
        map.put("token", tokenService.createTokenStudy(loginUserParent));
        // 获取登录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);
    }
@@ -736,7 +752,7 @@
            byId.setPhone(phone);
        }
        // 手机验证码校验
        if (StringUtils.hasLength(phoneCode)){
        if (StringUtils.hasLength(phoneCode)) {
            if (!phoneCode.equals("123456")) {
                Object redisPhoneCode = redisService.getCacheObject(RedisConstants.PHONE_CODE + phone);
                if (null == redisPhoneCode) {
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TStudyListen.java
@@ -57,4 +57,5 @@
     */
    @ApiModelProperty("非会员是否查看 0否1是")
    private Integer isVip;
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TSubjectRecord.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;
@@ -45,12 +46,12 @@
    /**
     * 上次回答到的题组id
     */
    @ApiModelProperty(value = "上次回答到的题组id")
    private Integer beforeSubject;
    @ApiModelProperty(value = "上次回答到的题组id(, 拼接)")
    private String beforeSubject;
    /**
     * 类型1听音选图2看图选音3归纳排除4有问有答5音图相配
     */
    @ApiModelProperty(value = "类型1听音选图2看图选音3归纳排除4有问有答5音图相配")
    @ApiModelProperty(value = "类型1:听音选图,2:看图选音,3:归纳排除,4:有问有答,5:音图相配")
    private Integer type;
    /**
     * 已回答正确的题目id 多个逗号隔开
@@ -58,4 +59,18 @@
    @ApiModelProperty(value = "已回答正确的题目id 多个逗号隔开")
    private String completeSubject;
    /**
     * 答题次数
     */
    @ApiModelProperty(value = "答题次数")
    @TableField("answerNumber")
    private Integer answerNumber;
    /**
     * 答题正确次数
     */
    @ApiModelProperty(value = "答题正确次数")
    @TableField("correctNumber")
    private Integer correctNumber;
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TUserStudy.java
@@ -70,29 +70,36 @@
    @ApiModelProperty(value = "本月学习时长")
    private Integer monthStudy;
    /**
     * 故事名称
     * 听音选图
     */
    @ApiModelProperty(value = "听音选图学习进度(100为已完成)")
    private Integer listen;
    /**
     * 故事名称
     * 看图选音
     */
    @ApiModelProperty(value = "看图选音学习进度(100为已完成)")
    private Integer look;
    /**
     * 故事名称
     * 归纳排除
     */
    @ApiModelProperty(value = "归纳排除学习进度(100为已完成)")
    private Integer induction;
    /**
     * 故事名称
     * 有问有答
     */
    @ApiModelProperty(value = "有问有答学习进度(100为已完成)")
    private Integer answer;
    /**
     * 故事名称
     * 音图相配
     */
    @ApiModelProperty(value = "音图相配学习进度(100为已完成)")
    private Integer pair;
    /**
     * 当前week学习进度
     */
    @ApiModelProperty(value = "当前week学习进度")
    @TableField(exist = false)
    private Integer computeSchedule;
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/domain/TUserStudyRecord.java
New file
@@ -0,0 +1,79 @@
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;
/**
 * <p>
 * 学习类型 听 听音选图
 * </p>
 *
 * @author 无关风月
 * @since 2024-04-26
 */
@Data
@TableName("t_user_study_record")
public class TUserStudyRecord {
    private static final long serialVersionUID = 1L;
    /**
     * 主键id
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    /**
     * 季度
     */
    @ApiModelProperty("季度")
    @TableField("user_id")
    private Integer userId;
    /**
     * 季度
     */
    @ApiModelProperty("季度")
    @TableField("quarter")
    private Integer quarter;
    /**
     * 周目x
     */
    @ApiModelProperty("周目")
    @TableField("week")
    private Integer week;
    /**
     * day
     */
    @ApiModelProperty("所属day")
    @TableField("day")
    private Integer day;
    /**
     * 题目
     */
    @ApiModelProperty("获取积分数量")
    @TableField("obtained_integral")
    private Integer obtainedIntegral;
    /**
     * 0:day 1-5学习;1:自主故事1
     */
    @ApiModelProperty("0:day 1-5学习;1:自主故事1")
    @TableField("type")
    private Integer type;
    /**
     * 自主故事id
     */
    @ApiModelProperty("自主故事id")
    @TableField("story_id")
    private Integer storyId;
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/dto/CompleteStudyDTO.java
@@ -4,7 +4,6 @@
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
 * @author HJL
@@ -24,13 +23,7 @@
     * 题目id数组
     */
    @ApiModelProperty("题目id数组")
    private List<Integer> studyIds;
    /**
     * 该学习是否完成
     */
    @ApiModelProperty("该学习是否完成(如果已完成再次进入学习并完成学习后,该字段传值 false)")
    private Boolean isComplete;
    private String studyIds;
    /**
     * 学习时长
@@ -39,4 +32,28 @@
    @NotNull(message = "本次学习时长不能为空!")
    private Integer studyTime;
    /**
     * 正确率
     */
    @ApiModelProperty("正确率")
    private Integer accuracy;
    /**
     * 季度
     */
    @ApiModelProperty("季度")
    private Integer quarter;
    /**
     * 周目
     */
    @ApiModelProperty("周目")
    private Integer week;
    /**
     * 所属day
     */
    @ApiModelProperty("所属day")
    private Integer day;
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/dto/StudyWeekDTO.java
@@ -14,7 +14,7 @@
public class StudyWeekDTO extends StudyDTO {
    @ApiModelProperty("完成后可获积分数")
    private Long totalIntegral;
    private Integer totalIntegral;
    @ApiModelProperty("所属季度")
    private Integer quarter;
@@ -25,4 +25,11 @@
    @ApiModelProperty("study表Id")
    private String id;
    public StudyWeekDTO(Integer week, Integer type, Integer quarter, String title, Integer total) {
        super.setWeek(week);
        super.setType(type);
        this.quarter = quarter;
        this.title = title;
        this.totalIntegral = total;
    }
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/mapper/TStoryListenMapper.java
@@ -4,8 +4,6 @@
import com.ruoyi.study.domain.TStoryListen;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * <p>
 * 听故事 Mapper 接口
@@ -23,5 +21,5 @@
     * @param week    周
     * @return 故事信息
     */
    List<TStoryListen> storyDetail(@Param("quarter") Integer quarter, @Param("week") Integer week);
    TStoryListen storyDetail(@Param("quarter") Integer quarter, @Param("week") Integer week);
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/mapper/UserStudyRecordMapper.java
New file
@@ -0,0 +1,16 @@
package com.ruoyi.study.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.study.domain.TUserStudyRecord;
/**
 * <p>
 * 部门表 Mapper 接口
 * </p>
 *
 * @author 无关风月
 * @since 2024-04-26
 */
public interface UserStudyRecordMapper extends BaseMapper<TUserStudyRecord> {
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITGameService.java
@@ -38,4 +38,5 @@
     * @return 游戏信息
     */
    TGame gameHearing(Integer quarter, Integer week);
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITStoryListenService.java
@@ -3,8 +3,6 @@
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.study.domain.TStoryListen;
import java.util.List;
/**
 * <p>
 * 听故事 服务类
@@ -22,5 +20,5 @@
     * @param week    周
     * @return 故事信息
     */
    List<TStoryListen> storyDetail(Integer quarter, Integer week);
    TStoryListen storyDetail(Integer quarter, Integer week);
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITStoryService.java
@@ -2,6 +2,7 @@
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.study.domain.TStory;
import com.ruoyi.study.domain.TStoryListen;
import com.ruoyi.study.dto.SubjectQuery;
import com.ruoyi.study.vo.SubjectVO;
@@ -18,4 +19,13 @@
public interface ITStoryService extends IService<TStory> {
    List<SubjectVO> listAll(SubjectQuery query);
    /**
     * 自主故事,获取图片及语音
     *
     * @param storyListen 听故事信息
     * @param type 类型 0:看图配音;1:超级记忆
     * @return 语音及图片列表
     */
    List<TStory> lookPictureDbu(TStoryListen storyListen,int type);
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITStudyService.java
@@ -67,8 +67,8 @@
    /**
     * 自主学习3-归纳排除
     *
     * @param week 周目
     * @param day  所属day
     * @param week          周目
     * @param day           所属day
     * @param inductionList 归纳排除
     * @return 题目信息
     */
@@ -77,8 +77,8 @@
    /**
     * 自主学习4-有问有答
     *
     * @param week 周目
     * @param day  所属day
     * @param week       周目
     * @param day        所属day
     * @param answerList 有问有答
     * @return 题目信息
     */
@@ -94,4 +94,22 @@
     */
    StudyPairResultVO pictureMateVoice(Integer week, Integer day, List<TStudyPair> pair);
    /**
     * 计算用户当前week的学习进度
     *
     * @param result 用户学习信息
     * @param week   周目
     * @return 当前week学习进度
     */
    int computeSchedule(TUserStudy result, Integer week);
    /**
     * 获取本次学习可获得总积分
     *
     * @param studyIds 题组id
     * @param type     类型
     * @param accuracy 正确率
     * @return 积分
     */
    int computeTotalIntegral(List<String> studyIds, Integer type, Integer accuracy);
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITSubjectRecordService.java
@@ -1,8 +1,9 @@
package com.ruoyi.study.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.study.domain.TGameRecord;
import com.ruoyi.study.domain.TSubjectRecord;
import com.ruoyi.study.vo.ExitLearnVO;
import com.ruoyi.study.vo.SubjectRecordResultVO;
/**
 * <p>
@@ -14,4 +15,21 @@
 */
public interface ITSubjectRecordService extends IService<TSubjectRecord> {
    /**
     * 退出学习,保存学习记录
     *
     * @param exitLearn 学习信息
     * @param userid    用户id
     * @return 保存结果
     */
    Boolean exitLearning(ExitLearnVO exitLearn, Integer userid);
    /**
     * 获取学习进度
     *
     * @param subjectRecord 已存在的学习进度
     * @param userid        用户id
     * @return 结果
     */
    SubjectRecordResultVO recordResult(TSubjectRecord subjectRecord, Integer userid);
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/IUserStudyRecordService.java
New file
@@ -0,0 +1,17 @@
package com.ruoyi.study.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.study.domain.TUserStudyRecord;
/**
 * <p>
 * 部门表 服务类
 * </p>
 *
 * @author 无关风月
 * @since 2024-04-26
 */
public interface IUserStudyRecordService extends IService<TUserStudyRecord> {
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TGameServiceImpl.java
@@ -1,14 +1,20 @@
package com.ruoyi.study.service.impl;
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.study.domain.TGame;
import com.ruoyi.study.domain.TIntegralRecord;
import com.ruoyi.study.domain.TSubject;
import com.ruoyi.study.dto.CompleteGameDTO;
import com.ruoyi.study.mapper.TGameMapper;
import com.ruoyi.study.service.ITGameService;
import com.ruoyi.study.vo.StudyGameMemoryVO;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
/**
@@ -45,4 +51,5 @@
    public TGame gameHearing(Integer quarter, Integer week) {
        return baseMapper.gameHearing(quarter, week);
    }
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TStoryListenServiceImpl.java
@@ -2,11 +2,9 @@
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.study.domain.TStoryListen;
import com.ruoyi.study.service.ITStoryListenService;
import com.ruoyi.study.mapper.TStoryListenMapper;
import com.ruoyi.study.service.ITStoryListenService;
import org.springframework.stereotype.Service;
import java.util.List;
/**
 * <p>
@@ -20,7 +18,7 @@
public class TStoryListenServiceImpl extends ServiceImpl<TStoryListenMapper, TStoryListen> implements ITStoryListenService {
    @Override
    public List<TStoryListen> storyDetail(Integer quarter, Integer week) {
    public TStoryListen storyDetail(Integer quarter, Integer week) {
        return baseMapper.storyDetail(quarter, week);
    }
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TStoryServiceImpl.java
@@ -2,13 +2,17 @@
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.study.domain.TStory;
import com.ruoyi.study.domain.TStoryListen;
import com.ruoyi.study.dto.SubjectQuery;
import com.ruoyi.study.mapper.TStoryMapper;
import com.ruoyi.study.service.ITStoryService;
import com.ruoyi.study.vo.SubjectVO;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
 * <p>
@@ -25,4 +29,22 @@
    public List<SubjectVO> listAll(SubjectQuery query) {
        return this.baseMapper.listAll(query);
    }
    @Override
    public List<TStory> lookPictureDbu(TStoryListen storyListen, int type) {
        List<TStory> storyList = new ArrayList<>();
        List<String> list;
        // 分类
        if (0 == type) {
            list = Arrays.stream(storyListen.getLookStory().split(",")).collect(Collectors.toList());
        } else {
            list = Arrays.stream(storyListen.getStory().split(",")).collect(Collectors.toList());
        }
        // 获取图片及语音集合
        for (String s : list) {
            TStory story = this.lambdaQuery().eq(TStory::getId, s).eq(TStory::getDisabled, 0).one();
            storyList.add(story);
        }
        return storyList;
    }
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TStudyServiceImpl.java
@@ -8,10 +8,7 @@
import com.ruoyi.study.domain.*;
import com.ruoyi.study.dto.StudyWeekDTO;
import com.ruoyi.study.mapper.TStudyMapper;
import com.ruoyi.study.service.ITGameRecordService;
import com.ruoyi.study.service.ITStudyService;
import com.ruoyi.study.service.ITSubjectService;
import com.ruoyi.study.service.ITUserStudyService;
import com.ruoyi.study.service.*;
import com.ruoyi.study.vo.*;
import org.springframework.stereotype.Service;
@@ -38,17 +35,86 @@
    private ITGameRecordService gameRecordService;
    @Resource
    private TokenService tokenService;
    @Resource
    private ITStudyAnswerService studyAnswerService;
    @Resource
    private ITStudyInductionService studyInductionService;
    @Resource
    private ITStudyLookService studyLookService;
    @Resource
    private ITStudyListenService studyListenService;
    @Resource
    private ITStudyPairService studyPairService;
    @Resource
    private ITGameService gameService;
    @Resource
    private ITStoryListenService storyListenService;
    private final static Map<String, Integer> GAME_DIFFICULTY_MAP = new HashMap<>();
    private final static Map<Integer, Integer> GAME_DIFFICULTY_MAP = new HashMap<>();
    static {
        GAME_DIFFICULTY_MAP.put("1", 0);
        GAME_DIFFICULTY_MAP.put("2", 1);
        GAME_DIFFICULTY_MAP.put(1, 0);
        GAME_DIFFICULTY_MAP.put(2, 1);
    }
    @Override
    public List<StudyWeekDTO> weekList(Integer type, Integer quarter) {
        return baseMapper.weekList(type, quarter);
        List<StudyWeekDTO> result = new ArrayList<>();
        // 根据季度和type查询学习配置
        List<TStudy> study = lambdaQuery().eq(TStudy::getQuarter, quarter).eq(TStudy::getType, type)
                .eq(TStudy::getDisabled, 0).orderByAsc(TStudy::getWeek).list();
        for (TStudy item : study) {
            Integer week = item.getWeek();
            String title = item.getTitle();
            Integer id = item.getId();
            // 计算总积分
            int total = 0;
            // 有问有答
            List<TStudyAnswer> answerList = studyAnswerService.lambdaQuery().eq(TStudyAnswer::getStudyId, id)
                    .eq(TStudyAnswer::getDisabled, 0).list();
            total += answerList.stream().map(TStudyAnswer::getIntegral).mapToInt(Integer::intValue).sum();
            // 归纳判断
            List<TStudyInduction> inductionList = studyInductionService.lambdaQuery().eq(TStudyInduction::getStudyId, id)
                    .eq(TStudyInduction::getDisabled, 0).list();
            total += inductionList.stream().map(TStudyInduction::getIntegral).mapToInt(Integer::intValue).sum();
            // 看图选音
            List<TStudyLook> lookList = studyLookService.lambdaQuery().eq(TStudyLook::getStudyId, id)
                    .eq(TStudyLook::getDisabled, 0).list();
            total += lookList.stream().map(TStudyLook::getIntegral).mapToInt(Integer::intValue).sum();
            // 听音选图
            List<TStudyListen> listenList = studyListenService.lambdaQuery().eq(TStudyListen::getStudyId, id)
                    .eq(TStudyListen::getDisabled, 0).list();
            total += listenList.stream().map(TStudyListen::getIntegral).mapToInt(Integer::intValue).sum();
            // 音图相配
            List<TStudyPair> pairList = studyPairService.lambdaQuery().eq(TStudyPair::getStudyId, id)
                    .eq(TStudyPair::getDisabled, 0).list();
            total += pairList.stream().map(TStudyPair::getIntegral).mapToInt(Integer::intValue).sum();
            // 自主游戏
            List<TGame> gameList = gameService.lambdaQuery().eq(TGame::getStudyId, id)
                    .eq(TGame::getDisabled, 0).list();
            // 自主游戏-超级听力
            List<String> gameIntegral = gameList.stream().map(TGame::getIntegral).collect(Collectors.toList());
            for (String s : gameIntegral) {
                List<String> list = Arrays.stream(s.split(",")).collect(Collectors.toList());
                total += list.stream().mapToInt(Integer::parseInt).sum();
            }
            // 自主游戏-框架记忆
            List<Integer> gameAnswerIntegral = gameList.stream().map(TGame::getAnswerIntegral).collect(Collectors.toList());
            for (Integer integral : gameAnswerIntegral) {
                if (null != integral) {
                    total += integral;
                }
            }
            // 自主故事
            List<TStoryListen> storyListenList = storyListenService.lambdaQuery().eq(TStoryListen::getStudyId, id)
                    .eq(TStoryListen::getDisabled, 0).list();
            // 自主故事 - 框架记忆
            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));
        }
        return result;
    }
    @Override
@@ -60,15 +126,17 @@
    public void checkDifficulty(Integer difficulty, Integer week, TGame game) {
        // 判断用户是否完成上一个等级
        if (!Constants.ZERO.equals(difficulty)) {
            Integer level = GAME_DIFFICULTY_MAP.get(String.valueOf(difficulty));
            Integer level = GAME_DIFFICULTY_MAP.get(difficulty);
            if (null == level) {
                throw new GlobalException("游戏等级异常,请重试!");
            }
            // 获取用户游戏进度
            Integer userId = tokenService.getLoginUserStudy().getUserid();
            List<TGameRecord> list = gameRecordService.lambdaQuery().eq(TGameRecord::getUserId, userId).eq(TGameRecord::getGameId, game.getId()).list();
            boolean contains = list.stream().map(TGameRecord::getGameDifficulty).collect(Collectors.toList()).contains(level);
            if (!contains) {
            List<TGameRecord> list = gameRecordService.lambdaQuery().eq(TGameRecord::getUserId, userId)
                    .eq(TGameRecord::getGameId, game.getId())
                    .eq(TGameRecord::getAccuracy, 100)
                    .eq(TGameRecord::getGameDifficulty, level).list();
            if (list.isEmpty()) {
                throw new GlobalException("请先完成上一难度再挑战当前难度!");
            }
        }
@@ -79,16 +147,33 @@
        if (studyListens.isEmpty()) {
            throw new GlobalException("当前学习周目题目数量不足!");
        }
        // 随机获取一组题
        Random rand = new Random();
        TStudyListen data;
        if (studyListens.size() == 1) {
            data = studyListens.get(0);
        } else {
            data = studyListens.get(rand.nextInt(studyListens.size()));
        // 题组信息
        LearnStudyVO learnStudy = new LearnStudyVO();
        String ids = studyListens.stream().map(TStudyListen::getId).map(String::valueOf)
                .collect(Collectors.joining(","));
        learnStudy.setId(ids);
        int total = 0;
        for (TStudyListen data : studyListens) {
            if (null != data) {
                total += data.getIntegral();
            }
        }
        List<TSubject> subjectList = getSubjects(data.getSubject().split(","));
        return new StudyListenResultVO(data, subjectList);
        learnStudy.setIntegral(total);
        // 语音及图片
        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) {
                TSubject data = subjectService.lambdaQuery().eq(TSubject::getId, id)
                        .eq(TSubject::getDisabled, 0).one();
                list.add(data);
            }
            subjectList.add(list);
        }
        return new StudyListenResultVO(learnStudy, subjectList);
    }
    @Override
@@ -96,16 +181,33 @@
        if (lookList.isEmpty()) {
            throw new GlobalException("当前学习周目题目数量不足!");
        }
        // 随机获取一组题
        Random rand = new Random();
        TStudyLook data;
        if (lookList.size() == 1) {
            data = lookList.get(0);
        } else {
            data = lookList.get(rand.nextInt(lookList.size()));
        // 题组信息
        LearnStudyVO learnStudy = new LearnStudyVO();
        String ids = lookList.stream().map(TStudyLook::getId).map(String::valueOf)
                .collect(Collectors.joining(","));
        learnStudy.setId(ids);
        int total = 0;
        for (TStudyLook data : lookList) {
            if (null != data) {
                total += data.getIntegral();
            }
        }
        List<TSubject> subjectList = getSubjects(data.getSubject().split(","));
        return new StudyLookResultVO(data, subjectList);
        learnStudy.setIntegral(total);
        // 语音及图片
        List<List<TSubject>> subjectList = new ArrayList<>();
        for (TStudyLook studyLook : lookList) {
            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)
                        .eq(TSubject::getDisabled, 0).one();
                list.add(data);
            }
            subjectList.add(list);
        }
        return new StudyLookResultVO(learnStudy, subjectList);
    }
    @Override
@@ -113,23 +215,33 @@
        if (inductionList.isEmpty()) {
            throw new GlobalException("当前学习周目题目数量不足!");
        }
        // 随机获取一组题
        Random rand = new Random();
        TStudyInduction data;
        if (inductionList.size() == 1) {
            data = inductionList.get(0);
        } else {
            data = inductionList.get(rand.nextInt(inductionList.size()));
        }
        String[] ids = data.getSubject().split(",");
        List<TSubject> subjectList = new ArrayList<>();
        for (String id : ids) {
            if (id.startsWith("-")) {
                id = id.replace("-", "");
        // 题组信息
        LearnStudyVO learnStudy = new LearnStudyVO();
        String ids = inductionList.stream().map(TStudyInduction::getId).map(String::valueOf)
                .collect(Collectors.joining(","));
        learnStudy.setId(ids);
        int total = 0;
        for (TStudyInduction data : inductionList) {
            if (null != data) {
                total += data.getIntegral();
            }
            subjectList.add(subjectService.getById(id));
        }
        return new StudyInductionResultVO(data, subjectList);
        learnStudy.setIntegral(total);
        // 语音及图片
        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("-", "");
                }
                subjectLists.add(subjectService.getById(id));
            }
            subjectList.add(subjectLists);
        }
        return new StudyInductionResultVO(learnStudy, subjectList);
    }
    @Override
@@ -137,37 +249,56 @@
        if (answerList.isEmpty()) {
            throw new GlobalException("当前学习周目题目数量不足!");
        }
        // 随机获取一组题
        Random rand = new Random();
        TStudyAnswer data;
        TStudyAnswer dataTwo;
        if (answerList.size() == 1) {
            data = answerList.get(0);
            dataTwo = answerList.get(0);
        } else {
            data = answerList.get(rand.nextInt(answerList.size()));
            dataTwo = answerList.get(rand.nextInt(answerList.size()));
        // 题组信息
        LearnStudyVO learnStudy = new LearnStudyVO();
        String ids = answerList.stream().map(TStudyAnswer::getId).map(String::valueOf)
                .collect(Collectors.joining(","));
        learnStudy.setId(ids);
        int total = 0;
        for (TStudyAnswer data : answerList) {
            if (null != data) {
                total += data.getIntegral();
            }
        }
        AnswerVO one = new AnswerVO();
        BeanUtils.copyProperties(data, one);
        answerList.remove(data);
        AnswerVO two = new AnswerVO();
        BeanUtils.copyProperties(dataTwo, two);
        // 获取问题题目 和 回答题目
        List<String> ids = new ArrayList<>();
        ids.add(String.valueOf(one.getSubject()));
        ids.add(String.valueOf(one.getAnswerSubject()));
        // 有问有答
        List<TStudyAnswer> answers = new ArrayList<>();
        answers.add(one);
        one.setSubjectList(getSubjects(ids.toArray(new String[0])));
        // 第二题信息
        List<String> twoIds = new ArrayList<>();
        answers.add(two);
        twoIds.add(String.valueOf(two.getSubject()));
        twoIds.add(String.valueOf(two.getAnswerSubject()));
        two.setSubjectList(getSubjects(twoIds.toArray(new String[0])));
        return new StudyAnswerResultVO(answers);
        learnStudy.setIntegral(total);
        // 题目语音及图片信息
        List<List<QuestionsAnswersSubjectVO>> subjectList = new ArrayList<>();
        for (int i = 0; i < answerList.size(); i += Constants.TWO) {
            List<QuestionsAnswersSubjectVO> voList = new ArrayList<>();
            // 一组题目为四道题,
            TStudyAnswer one = answerList.get(i);
            TStudyAnswer two = answerList.get(i + 1);
            voAdd(voList, one);
            voAdd(voList, two);
            subjectList.add(voList);
        }
        return new StudyAnswerResultVO(learnStudy, subjectList);
    }
    private void voAdd(List<QuestionsAnswersSubjectVO> voList, TStudyAnswer one) {
        // 第一道题问题及答案
        Integer subject = one.getSubject();
        Integer answerSubject = one.getAnswerSubject();
        // 问题题目信息
        QuestionsAnswersSubjectVO oneVO = new QuestionsAnswersSubjectVO();
        TSubject one1 = subjectService.lambdaQuery().eq(TSubject::getId, subject)
                .eq(TSubject::getDisabled, 0).one();
        BeanUtils.copyProperties(one1, oneVO);
        // 回答题目信息
        QuestionsAnswersSubjectVO twoVO = new QuestionsAnswersSubjectVO();
        TSubject two1 = subjectService.lambdaQuery().eq(TSubject::getId, answerSubject)
                .eq(TSubject::getDisabled, 0).one();
        BeanUtils.copyProperties(two1, twoVO);
        // 判断第一组题目的问题题目及回答题目,哪个是答案
        if (Constants.ZERO.equals(one.getIsAnswer())) {
            oneVO.setIsQuestion(0);
            twoVO.setIsQuestion(1);
        } else {
            oneVO.setIsQuestion(1);
            twoVO.setIsQuestion(0);
        }
        voList.add(oneVO);
        voList.add(twoVO);
    }
    @Override
@@ -175,32 +306,136 @@
        if (pair.isEmpty()) {
            throw new GlobalException("当前学习周目题目数量不足!");
        }
        // 随机获取一组题
        Random rand = new Random();
        TStudyPair data;
        if (pair.size() == 1) {
            data = pair.get(0);
        } else {
            data = pair.get(rand.nextInt(pair.size()));
        // 题组信息
        LearnStudyVO learnStudy = new LearnStudyVO();
        String ids = pair.stream().map(TStudyPair::getId).map(String::valueOf)
                .collect(Collectors.joining(","));
        learnStudy.setId(ids);
        int total = 0;
        for (TStudyPair data : pair) {
            if (null != data) {
                total += data.getIntegral();
            }
        }
        List<TSubject> subjectList = getSubjects(data.getSubject().split(","));
        return new StudyPairResultVO(data, subjectList);
        learnStudy.setIntegral(total);
        // 语音及图片
        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("-")) {
                    id = id.replace("-", "");
                }
                subjectLists.add(subjectService.getById(id));
            }
            subjectList.add(subjectLists);
        }
        return new StudyPairResultVO(learnStudy, subjectList);
    }
    /**
     * 根据参数id查询图片及语音
     *
     * @param ids 多个id
     * @return 图片及语音集合
     */
    private List<TSubject> getSubjects(String[] ids) {
        List<TSubject> list = new ArrayList<>();
        for (String id : ids) {
            TSubject data = subjectService.lambdaQuery().eq(TSubject::getId, id)
                    .eq(TSubject::getDisabled, 0).one();
            list.add(data);
    @Override
    public int computeSchedule(TUserStudy result, Integer week) {
        // 基础学习进度
        Integer listen = result.getListen();
        Integer look = result.getLook();
        Integer induction = result.getInduction();
        Integer answer = result.getAnswer();
        Integer pair = result.getPair();
        Integer day = result.getDay();
        // 默认进度为 0
        int defaultSchedule;
        // week以超过当前week,进度为 100%
        if (result.getWeek() > week) {
            defaultSchedule = 100;
        } else {
            // 根据day初始化学习进度
            if (Constants.ONE.equals(day)) {
                defaultSchedule = 0;
            } else if (Constants.TWO.equals(day)) {
                defaultSchedule = 20;
            } else if (Constants.THREE.equals(day)) {
                defaultSchedule = 40;
            } else if (Constants.FOUR.equals(day)) {
                defaultSchedule = 60;
            } else if (Constants.FIVE.equals(day)) {
                defaultSchedule = 80;
            } else {
                defaultSchedule = 0;
            }
            // 进度学习完成度计算总学习进度
            if (!Constants.ZERO.equals(listen) && !Constants.BURDEN_ONE.equals(listen)) {
                defaultSchedule += 4 * (100 / listen);
            }
            if (!Constants.ZERO.equals(look) && !Constants.BURDEN_ONE.equals(look)) {
                defaultSchedule += 4 * (100 / look);
            }
            if (!Constants.ZERO.equals(induction) && !Constants.BURDEN_ONE.equals(induction)) {
                defaultSchedule += 4 * (100 / induction);
            }
            if (!Constants.ZERO.equals(answer) && !Constants.BURDEN_ONE.equals(answer)) {
                defaultSchedule += 4 * (100 / answer);
            }
            if (!Constants.ZERO.equals(pair) && !Constants.BURDEN_ONE.equals(pair)) {
                defaultSchedule += 4 * (100 / pair);
            }
        }
        return list;
        return defaultSchedule;
    }
    @Override
    public int computeTotalIntegral(List<String> studyIds, Integer type, Integer accuracy) {
        int sum;
        if (Constants.ONE.equals(type)) {
            List<TStudyListen> list = studyListenService.lambdaQuery().in(TStudyListen::getId, studyIds)
                    .eq(TStudyListen::getDisabled, 0).list();
            Optional<TStudyListen> any = list.stream().findAny();
            if (any.isPresent()) {
                sum = any.get().getIntegral();
            } else {
                sum = 0;
            }
        } else if (Constants.TWO.equals(type)) {
            List<TStudyLook> list = studyLookService.lambdaQuery().in(TStudyLook::getId, studyIds)
                    .eq(TStudyLook::getDisabled, 0).list();
            Optional<TStudyLook> any = list.stream().findAny();
            if (any.isPresent()) {
                sum = any.get().getIntegral();
            } else {
                sum = 0;
            }
        } else if (Constants.THREE.equals(type)) {
            List<TStudyInduction> list = studyInductionService.lambdaQuery().in(TStudyInduction::getId, studyIds)
                    .eq(TStudyInduction::getDisabled, 0).list();
            Optional<TStudyInduction> any = list.stream().findAny();
            if (any.isPresent()) {
                sum = any.get().getIntegral();
            } else {
                sum = 0;
            }
        } else if (Constants.FOUR.equals(type)) {
            List<TStudyAnswer> list = studyAnswerService.lambdaQuery().in(TStudyAnswer::getId, studyIds)
                    .eq(TStudyAnswer::getDisabled, 0).list();
            Optional<TStudyAnswer> any = list.stream().findAny();
            if (any.isPresent()) {
                sum = any.get().getIntegral();
            } else {
                sum = 0;
            }
        } else if (Constants.FIVE.equals(type)) {
            List<TStudyPair> list = studyPairService.lambdaQuery().in(TStudyPair::getId, studyIds)
                    .eq(TStudyPair::getDisabled, 0).list();
            Optional<TStudyPair> any = list.stream().findAny();
            if (any.isPresent()) {
                sum = any.get().getIntegral();
            } else {
                sum = 0;
            }
        } else {
            throw new GlobalException("题目信息异常!");
        }
        return (int) (sum * ((double) accuracy / 100));
    }
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TSubjectRecordServiceImpl.java
@@ -1,13 +1,16 @@
package com.ruoyi.study.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.study.domain.TGameRecord;
import com.ruoyi.study.domain.TSubjectRecord;
import com.ruoyi.study.mapper.TGameRecordMapper;
import com.ruoyi.study.mapper.TSubjectRecordMapper;
import com.ruoyi.study.service.ITGameRecordService;
import com.ruoyi.study.service.ITSubjectRecordService;
import com.ruoyi.study.vo.ExitLearnVO;
import com.ruoyi.study.vo.SubjectRecordResultVO;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
 * <p>
@@ -20,4 +23,33 @@
@Service
public class TSubjectRecordServiceImpl extends ServiceImpl<TSubjectRecordMapper, TSubjectRecord> implements ITSubjectRecordService {
    @Override
    public Boolean exitLearning(ExitLearnVO exitLearn, Integer userid) {
        Integer week = exitLearn.getWeek();
        Integer day = exitLearn.getDay();
        Integer type = exitLearn.getType();
        String topicIds = exitLearn.getTopicIds();
        String teamIds = exitLearn.getTeamIds();
        // 封装信息
        TSubjectRecord subjectRecord = new TSubjectRecord();
        subjectRecord.setUserId(userid);
        subjectRecord.setWeek(week);
        subjectRecord.setDay(day);
        subjectRecord.setType(type);
        // 答题次数与答题正确次数
        subjectRecord.setAnswerNumber(exitLearn.getAnswerNumber());
        subjectRecord.setCorrectNumber(exitLearn.getCorrectNumber());
        subjectRecord.setType(type);
        // 题目与题组需处理
        List<String> teamIdList = Arrays.stream(teamIds.split(",")).collect(Collectors.toList());
        List<String> topicIdList = Arrays.stream(topicIds.split(",")).collect(Collectors.toList());
        subjectRecord.setBeforeSubject(teamIdList.stream().map(String::valueOf).collect(Collectors.joining(",")));
        subjectRecord.setCompleteSubject(topicIdList.stream().map(String::valueOf).collect(Collectors.joining(",")));
        return this.save(subjectRecord);
    }
    @Override
    public SubjectRecordResultVO recordResult(TSubjectRecord subjectRecord, Integer userid) {
        return null;
    }
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TUserServiceImpl.java
@@ -17,9 +17,10 @@
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;
import java.util.regex.Pattern;
/**
 * <p>
@@ -44,11 +45,20 @@
    @Autowired
    private HWSendSms hwSendSms;
    @Override
    public Boolean phoneCode(String phone) throws Exception {
        // 生成随机 6位数字 验证码
        String phoneCode = RandomUtil.randomNumbers(6);
        String regex = Constants.PHONE;
        // 编译正则表达式
        Pattern pattern = Pattern.compile(regex);
        // 创建Matcher对象
        Matcher matcher = pattern.matcher(phone);
        // 判断是否匹配
        if (!matcher.matches()) {
            throw new GlobalException("手机号不合法!");
        }
        hwSendSms.sendSms(phoneCode, phone);
        // 判断redis中是否存在手机验证码
        Object phoneCodeRedis = redisTemplate.opsForValue().get(RedisConstants.PHONE_CODE + phone);
@@ -79,15 +89,16 @@
    @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();
//        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;
    }
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TUserStudyServiceImpl.java
@@ -85,22 +85,32 @@
        Integer type = completeStudy.getType();
        if (Constants.ONE.equals(type)) {
            userStudyRecord.setListen(Constants.ONE_HUNDRED);
            userStudyRecord.setLook(Constants.BURDEN_ONE);
            userStudyRecord.setInduction(Constants.BURDEN_ONE);
            userStudyRecord.setAnswer(Constants.BURDEN_ONE);
            userStudyRecord.setPair(Constants.BURDEN_ONE);
        } else if (Constants.TWO.equals(type)) {
            userStudyRecord.setLook(Constants.ONE_HUNDRED);
            userStudyRecord.setInduction(Constants.BURDEN_ONE);
            userStudyRecord.setAnswer(Constants.BURDEN_ONE);
            userStudyRecord.setPair(Constants.BURDEN_ONE);
        } else if (Constants.THREE.equals(type)) {
            userStudyRecord.setInduction(Constants.ONE_HUNDRED);
            userStudyRecord.setAnswer(Constants.BURDEN_ONE);
            userStudyRecord.setPair(Constants.BURDEN_ONE);
        } else if (Constants.FOUR.equals(type)) {
            userStudyRecord.setAnswer(Constants.ONE_HUNDRED);
            userStudyRecord.setPair(Constants.BURDEN_ONE);
        } else if (Constants.FIVE.equals(type)) {
            // 类型五,说明当前day已经全部完成,更新学习记录的 day
            Integer nextDay = DAY_MAP.get(String.valueOf(userStudyRecord.getDay()));
            userStudyRecord.setDay(nextDay);
            // 学习day已切换更新学习进度及学习时长
            userStudyRecord.setListen(Constants.ZERO);
            userStudyRecord.setLook(Constants.ZERO);
            userStudyRecord.setInduction(Constants.ZERO);
            userStudyRecord.setAnswer(Constants.ZERO);
            userStudyRecord.setPair(Constants.ZERO);
            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);
            // 下一day为 1说明该周目已完成,应更改为下一周目
            if (Constants.ONE.equals(nextDay)) {
                // 获取下一周目信息
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/UserStudyRecordServiceImpl.java
New file
@@ -0,0 +1,20 @@
package com.ruoyi.study.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.study.domain.TUserStudyRecord;
import com.ruoyi.study.mapper.UserStudyRecordMapper;
import com.ruoyi.study.service.IUserStudyRecordService;
import org.springframework.stereotype.Service;
/**
 * <p>
 * 部门表 服务实现类
 * </p>
 *
 * @author 无关风月
 * @since 2024-04-26
 */
@Service
public class UserStudyRecordServiceImpl extends ServiceImpl<UserStudyRecordMapper, TUserStudyRecord> implements IUserStudyRecordService {
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/ExitLearnVO.java
New file
@@ -0,0 +1,56 @@
package com.ruoyi.study.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * @author HJL
 * @version 1.0
 * @since 2024-06-11 17:21
 */
@Data
public class ExitLearnVO {
    /**
     * 所属week
     */
    @ApiModelProperty("所属week")
    private Integer week;
    /**
     * 所属day
     */
    @ApiModelProperty("所属day")
    private Integer day;
    /**
     * 题目类型
     */
    @ApiModelProperty("题目类型(1:听音选图;2:看图选音;3:归纳排除;4:有问有答;5:音图相配)")
    private Integer type;
    /**
     * 题目id数组
     */
    @ApiModelProperty("回答正确的题目id")
    private String topicIds;
    /**
     * 题组id
     */
    @ApiModelProperty("题组id数组")
    private String teamIds;
    /**
     * 答题次数
     */
    @ApiModelProperty(value = "答题次数")
    private Integer answerNumber;
    /**
     * 答题正确次数
     */
    @ApiModelProperty(value = "答题正确次数")
    private Integer correctNumber;
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/GameMemoryPhotoVO.java
New file
@@ -0,0 +1,24 @@
package com.ruoyi.study.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * @author HJL
 * @version 1.0
 * @since 2024-06-13 11:32
 */
@Data
public class GameMemoryPhotoVO {
    @ApiModelProperty("游戏id")
    private Integer id;
    @ApiModelProperty("游戏图片")
    private String photo;
    public GameMemoryPhotoVO(Integer id, String photo) {
        this.id = id;
        this.photo = photo;
    }
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/GameMemoryVoiceVO.java
New file
@@ -0,0 +1,24 @@
package com.ruoyi.study.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * @author HJL
 * @version 1.0
 * @since 2024-06-13 11:32
 */
@Data
public class GameMemoryVoiceVO {
    @ApiModelProperty("游戏id")
    private Integer id;
    @ApiModelProperty("游戏语音")
    private String voice;
    public GameMemoryVoiceVO(Integer id, String voice) {
        this.id = id;
        this.voice = voice;
    }
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/LearnStudyVO.java
New file
@@ -0,0 +1,20 @@
package com.ruoyi.study.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * @author HJL
 * @version 1.0
 * @since 2024-06-13 18:36
 */
@Data
public class LearnStudyVO {
    @ApiModelProperty("拼接后的id")
    private String id;
    @ApiModelProperty("总积分")
    private Integer integral;
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/QuestionsAnswersSubjectVO.java
New file
@@ -0,0 +1,20 @@
package com.ruoyi.study.vo;
import com.ruoyi.study.domain.TSubject;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
 * @author HJL
 * @version 1.0
 * @since 2024-06-14 10:10
 */
@EqualsAndHashCode(callSuper = true)
@Data
public class QuestionsAnswersSubjectVO extends TSubject {
    @ApiModelProperty("答案是否为问题图片")
    private Integer isQuestion;
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyAnswerResultVO.java
@@ -1,6 +1,5 @@
package com.ruoyi.study.vo;
import com.ruoyi.study.domain.TStudyAnswer;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -14,15 +13,22 @@
 */
@Data
@ApiModel(value = "有问有答返回信息类")
public class StudyAnswerResultVO{
public class StudyAnswerResultVO {
    /**
     * 自主学习题目信息
     */
    @ApiModelProperty("自主学习题目信息")
    private List<TStudyAnswer> data;
    private LearnStudyVO data;
    public StudyAnswerResultVO(List<TStudyAnswer> data) {
    /**
     * 自主学习题目所包含录音图片等
     */
    @ApiModelProperty("自主学习题目所包含录音图片等")
    private List<List<QuestionsAnswersSubjectVO>> subjectList;
    public StudyAnswerResultVO(LearnStudyVO data, List<List<QuestionsAnswersSubjectVO>> subjectList) {
        this.data = data;
        this.subjectList = subjectList;
    }
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyGameMemoryVO.java
New file
@@ -0,0 +1,42 @@
package com.ruoyi.study.vo;
import com.ruoyi.study.domain.TGame;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
 * @author HJL
 * @version 1.0
 * @since 2024-05-22 14:48
 */
@Data
@ApiModel(value = "超级听力&&超级记忆返回信息类")
public class StudyGameMemoryVO {
    /**
     * 趣味游戏题目信息
     */
    @ApiModelProperty("趣味游戏题目信息")
    private TGame data;
    /**
     * 趣味游戏题目信息
     */
    @ApiModelProperty("游戏图片合集")
    private List<GameMemoryPhotoVO> photoList;
    /**
     * 趣味游戏题目信息
     */
    @ApiModelProperty("游戏语音合集")
    private List<GameMemoryVoiceVO> voiceList;
    public StudyGameMemoryVO(TGame data, List<GameMemoryPhotoVO> photoList, List<GameMemoryVoiceVO> voiceList) {
        this.data = data;
        this.photoList = photoList;
        this.voiceList = voiceList;
    }
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyGameResultVO.java
File was renamed from ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyGamerResultVO.java
@@ -5,7 +5,6 @@
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
@@ -14,10 +13,9 @@
 * @version 1.0
 * @since 2024-05-22 14:48
 */
@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel(value = "超级听力&&超级记忆返回信息类")
public class StudyGamerResultVO extends StudyModelVO {
public class StudyGameResultVO {
    /**
     * 趣味游戏题目信息
@@ -25,9 +23,12 @@
    @ApiModelProperty("趣味游戏题目信息")
    private TGame data;
    public StudyGamerResultVO(TGame data, List<TSubject> subjectList) {
    @ApiModelProperty("图片及语音信息")
    private List<TSubject> subjectList;
    public StudyGameResultVO(TGame data, List<TSubject> subjectList) {
        this.data = data;
        super.setSubjectList(subjectList);
        this.subjectList = subjectList;
    }
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyInductionResultVO.java
@@ -1,6 +1,5 @@
package com.ruoyi.study.vo;
import com.ruoyi.study.domain.TStudyInduction;
import com.ruoyi.study.domain.TSubject;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@@ -23,9 +22,9 @@
     * 自主学习题目信息
     */
    @ApiModelProperty("自主学习题目信息")
    private TStudyInduction data;
    private LearnStudyVO data;
    public StudyInductionResultVO(TStudyInduction data, List<TSubject> subjectList) {
    public StudyInductionResultVO(LearnStudyVO data, List<List<TSubject>> subjectList) {
        this.data = data;
        super.setSubjectList(subjectList);
    }
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyListenResultVO.java
@@ -1,6 +1,5 @@
package com.ruoyi.study.vo;
import com.ruoyi.study.domain.TStudyListen;
import com.ruoyi.study.domain.TSubject;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@@ -23,9 +22,9 @@
     * 自主学习题目信息
     */
    @ApiModelProperty("自主学习题目信息")
    private TStudyListen data;
    private LearnStudyVO data;
    public StudyListenResultVO(TStudyListen data, List<TSubject> subjectList) {
    public StudyListenResultVO(LearnStudyVO data, List<List<TSubject>> subjectList) {
        this.data = data;
        super.setSubjectList(subjectList);
    }
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyLookResultVO.java
@@ -1,6 +1,5 @@
package com.ruoyi.study.vo;
import com.ruoyi.study.domain.TStudyLook;
import com.ruoyi.study.domain.TSubject;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@@ -17,15 +16,15 @@
@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel(value = "看图选音返回信息类")
public class StudyLookResultVO extends StudyModelVO{
public class StudyLookResultVO extends StudyModelVO {
    /**
     * 自主学习题目信息
     */
    @ApiModelProperty("自主学习题目信息")
    private TStudyLook data;
    private LearnStudyVO data;
    public StudyLookResultVO(TStudyLook data, List<TSubject> subjectList) {
    public StudyLookResultVO(LearnStudyVO data, List<List<TSubject>> subjectList) {
        this.data = data;
        super.setSubjectList(subjectList);
    }
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyModelVO.java
@@ -18,6 +18,6 @@
     * 自主学习题目所包含录音图片等
     */
    @ApiModelProperty("自主学习题目所包含录音图片等")
    private List<TSubject> subjectList;
    private List<List<TSubject>> subjectList;
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyPairResultVO.java
@@ -1,11 +1,9 @@
package com.ruoyi.study.vo;
import com.ruoyi.study.domain.TStudyPair;
import com.ruoyi.study.domain.TSubject;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
@@ -14,18 +12,17 @@
 * @version 1.0
 * @since 2024-05-22 14:48
 */
@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel(value = "音图相配返回信息类")
public class StudyPairResultVO extends StudyModelVO {
public class StudyPairResultVO  extends StudyModelVO {
    /**
     * 自主学习题目信息
     */
    @ApiModelProperty("自主学习题目信息")
    private TStudyPair data;
    private LearnStudyVO data;
    public StudyPairResultVO(TStudyPair data, List<TSubject> subjectList) {
    public StudyPairResultVO(LearnStudyVO data, List<List<TSubject>> subjectList) {
        this.data = data;
        super.setSubjectList(subjectList);
    }
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyRecordVO.java
New file
@@ -0,0 +1,25 @@
package com.ruoyi.study.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * @author HJL
 * @version 1.0
 * @since 2024-06-14 11:24
 */
@Data
public class StudyRecordVO {
    @ApiModelProperty("可获得总积分")
    private Integer total;
    @ApiModelProperty("已获取积分")
    private Integer obtainedIntegral;
    public StudyRecordVO(Integer total, Integer obtainedIntegral) {
        this.total = total;
        this.obtainedIntegral = obtainedIntegral;
    }
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyStoryListenResultVO.java
@@ -1,7 +1,6 @@
package com.ruoyi.study.vo;
import com.ruoyi.study.domain.TStory;
import com.ruoyi.study.domain.TStoryListen;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -21,7 +20,7 @@
     * 自主故事-看图配音&&框架记忆题目信息
     */
    @ApiModelProperty("自主故事-看图配音&&框架记忆题目信息")
    private TStoryListen data;
    private StudyStoryVO data;
    /**
     * 自主学习题目所包含录音图片等
@@ -29,7 +28,7 @@
    @ApiModelProperty("故事列表")
    private List<TStory> storyList;
    public StudyStoryListenResultVO(TStoryListen data, List<TStory> storyList) {
    public StudyStoryListenResultVO(StudyStoryVO data, List<TStory> storyList) {
        this.data = data;
        this.storyList = storyList;
    }
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyStoryVO.java
New file
@@ -0,0 +1,20 @@
package com.ruoyi.study.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * @author HJL
 * @version 1.0
 * @since 2024-06-13 18:36
 */
@Data
public class StudyStoryVO {
    @ApiModelProperty("故事id")
    private Integer id;
    @ApiModelProperty("总积分")
    private Integer integral;
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/SubjectRecordResultVO.java
New file
@@ -0,0 +1,48 @@
package com.ruoyi.study.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
 * @author HJL
 * @version 1.0
 * @since 2024-06-12 14:57
 */
@Data
public class SubjectRecordResultVO {
    /**
     * 题组ids
     */
    @ApiModelProperty(value = "题组ids")
    private List<Integer> teamIds;
    /**
     * 已回答正确的题目id
     */
    @ApiModelProperty(value = "已回答正确的题目id")
    private List<Integer> topicIds;
    /**
     * 答题次数
     */
    @ApiModelProperty(value = "答题次数")
    private Integer answerNumber;
    /**
     * 答题正确次数
     */
    @ApiModelProperty(value = "答题正确次数")
    private Integer correctNumber;
    public SubjectRecordResultVO() {
    }
    public SubjectRecordResultVO(List<Integer> teamIds, List<Integer> topicIds, Integer answerNumber, Integer correctNumber) {
        this.teamIds = teamIds;
        this.topicIds = topicIds;
        this.answerNumber = answerNumber;
        this.correctNumber = correctNumber;
    }
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/UserPersonalCenterVO.java
@@ -23,4 +23,7 @@
        this.user = user;
        this.userStudy = userStudy;
    }
    public UserPersonalCenterVO() {
    }
}
ruoyi-service/ruoyi-study/src/main/resources/mapper/sutdy/TStudyMapper.xml
@@ -41,22 +41,9 @@
                 LEFT JOIN t_study_pair sp ON s.id = sp.studyId
                 LEFT JOIN t_story_listen sl ON s.id = sl.studyId
                 LEFT JOIN t_game g ON s.id = g.studyId
        <where>
            s.disabled = 0
              and sa.disabled = 0
              and si.disabled = 0
              and st.disabled = 0
              and sk.disabled = 0
              and sp.disabled = 0
              and sl.disabled = 0
              and g.disabled = 0
            <if test="quarter != null and quarter != ''">
                and s.quarter = #{quarter}
            </if>
            <if test="type != null and quarter != ''">
                and s.type = #{type}
            </if>
        </where>
        where s.disabled = 0
          and s.quarter = #{quarter}
          and s.type = #{type}
        GROUP BY s.week, s.title, s.quarter, s.id;
    </select>
</mapper>
ruoyi-service/ruoyi-study/src/main/resources/mapper/sutdy/UserStudyRecordMapper.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.UserStudyRecordMapper">
</mapper>