44323
2024-05-22 b265007b416705588737a34b01fdb5dbd7f58511
Merge branch 'master' of http://120.76.84.145:10101/gitblit/r/java/DolphinEnglish
13个文件已修改
10个文件已添加
616 ■■■■ 已修改文件
ruoyi-api/ruoyi-api-goods/src/main/java/com/ruoyi/goods/api/factory/GoodsFallbackFactory.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-goods/src/main/java/com/ruoyi/goods/api/feignClient/GoodsClient.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-study/src/main/java/com/ruoyi/study/api/factory/StudyFallbackFactory.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-study/src/main/java/com/ruoyi/study/api/feignClient/StudyClient.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/controller/TGoodsController.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/ITGoodsService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/TGoodsServiceImpl.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/vo/GoodDetailVO.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-goods/src/main/resources/mapper/goods/TGoodsMapper.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TStudyController.java 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TUserController.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITStudyService.java 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TStudyServiceImpl.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyAnswerResultVO.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyGamerResultVO.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyInductionResultVO.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyListenResultVO.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyLookResultVO.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyModelVO.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyPairResultVO.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyRecordResultVO.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyStoryListenResultVO.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-goods/src/main/java/com/ruoyi/goods/api/factory/GoodsFallbackFactory.java
@@ -70,7 +70,7 @@
            }
            @Override
            public R<List<TGoodsVO>> goodRecommend(String userId) {
            public R<List<TGoodsVO>> goodRecommend() {
                return R.fail("获取商品推荐列表" + cause.getMessage());
            }
        };
ruoyi-api/ruoyi-api-goods/src/main/java/com/ruoyi/goods/api/feignClient/GoodsClient.java
@@ -49,11 +49,10 @@
    /**
     * 可兑换商品推荐
     *
     * @param userId 用户id
     * @return 推荐商品信息
     */
    @GetMapping("/goodRecommend")
    @ApiOperation(value = "可兑换商品推荐", tags = {"可兑换商品推荐"})
    R<List<TGoodsVO>> goodRecommend(String userId);
    R<List<TGoodsVO>> goodRecommend();
}
ruoyi-api/ruoyi-api-study/src/main/java/com/ruoyi/study/api/factory/StudyFallbackFactory.java
@@ -134,6 +134,11 @@
            public R<Boolean> addIntegralDetail(String integral, String method) {
                return R.fail("生成积分明细信息失败" + cause.getMessage());
            }
            @Override
            public R<Boolean> exchangeIntegral(Integer integral, String method) {
                return R.fail("用户积分变动失败" + cause.getMessage());
            }
        };
    }
}
ruoyi-api/ruoyi-api-study/src/main/java/com/ruoyi/study/api/feignClient/StudyClient.java
@@ -186,8 +186,20 @@
     *
     * @param integral 积分变动信息
     * @param method   变动源
     * @return 操作结果
     */
    @GetMapping("/base/study/addIntegralDetail")
    R<Boolean> addIntegralDetail(@RequestParam("integral") String integral, @RequestParam("method") String method);
    /**
     * 用户积分变动(增加或减少)-用于远程调用
     *
     * @param integral 积分变动信息
     * @param method   变动源
     * @return 操作结果
     */
    @GetMapping("/base/study/exchangeIntegral")
    @ApiOperation(value = "用户积分变动", tags = {"用户积分变动"})
    R<Boolean> exchangeIntegral(@RequestParam("integral") Integer integral, @RequestParam("method") String method);
}
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java
@@ -149,6 +149,11 @@
    public static final String BURDEN = "-";
    /**
     * 积分明细 符号 -
     */
    public static final String INCREASE = "+";
    /**
     * 积分明细来源 商城消费
     */
    public static final String SHOPPING_CONSUME = "商城消费";
ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/controller/TGoodsController.java
@@ -11,6 +11,7 @@
import com.ruoyi.goods.dto.GoodQueryDTO;
import com.ruoyi.goods.dto.GoodsTypeQuery;
import com.ruoyi.goods.service.*;
import com.ruoyi.goods.vo.GoodDetailVO;
import com.ruoyi.goods.vo.TGoodsVO;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
@@ -22,9 +23,7 @@
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * <p>
@@ -176,6 +175,9 @@
     */
    @GetMapping("/confirm")
    @ApiOperation(value = "确认收货", tags = {"兑换记录"})
    @ApiImplicitParams({
            @ApiImplicitParam(value = "订单id", name = "id", dataType = "String", required = true)
    })
    public AjaxResult confirm(@RequestParam Integer id) {
        TOrder byId = orderService.getById(id);
        byId.setState(3);
@@ -241,12 +243,10 @@
    /**
     * 可兑换商品推荐
     * 远程调用
     */
    @GetMapping("/goodRecommend")
    @ApiOperation(value = "可兑换商品推荐", tags = {"可兑换商品推荐"})
    @ApiImplicitParams({
            @ApiImplicitParam(value = "商品id", name = "goodId", dataType = "String", required = true)
    })
    public R<List<TGoodsVO>> goodRecommend() {
        return R.ok(goodsService.goodRecommend(tokenService.getLoginUserStudy().getUserid()));
    }
@@ -261,21 +261,14 @@
    @ApiImplicitParams({
            @ApiImplicitParam(value = "商品id", name = "goodId", dataType = "String", required = true)
    })
    public AjaxResult<Map<String, Object>> goodDetail(@RequestParam String goodId) {
        Map<String, Object> result = new HashMap<>(8);
    public AjaxResult<GoodDetailVO> goodDetail(@RequestParam String goodId) {
        // 商品详情
        TGoods goods = goodsService.lambdaQuery().eq(TGoods::getId, goodId).one();
        result.put("goodDetail", goods);
        // 商品分类详情
        result.put("goodTypeDetail", goodsTypeService.lambdaQuery().in(TGoodsType::getId, Arrays.asList(goods.getTypeIds().split(","))).list());
        List<TGoodsType> goodsTypes = goodsTypeService.lambdaQuery().in(TGoodsType::getId, Arrays.asList(goods.getTypeIds().split(","))).list();
        // 已兑换人数
        result.put("number", goods.getBasicCount() + orderService.getGoodBuyNumber(goods.getId()));
        // 用户收货地址
        if (tokenService.getLoginUserStudy().getUserid() != null) {
            result.put("address", recipientService.lambdaQuery()
                    .eq(Recipient::getUserId, tokenService.getLoginUserStudy().getUserid()).eq(Recipient::getIsDefault, 1).one());
        }
        return AjaxResult.success(result);
        int number = goods.getBasicCount() + orderService.getGoodBuyNumber(goods.getId());
        return AjaxResult.success(new GoodDetailVO(goods, goodsTypes, number));
    }
    /**
@@ -286,9 +279,10 @@
    @ApiImplicitParams({
            @ApiImplicitParam(value = "商品id", name = "goodId", dataType = "String", required = true)
    })
    public AjaxResult<Map<String, Object>> redeemNow(@RequestParam String goodId) {
    public AjaxResult<GoodDetailVO> redeemNow(@RequestParam String goodId) {
        Recipient recipient = recipientService.lambdaQuery()
                .eq(Recipient::getUserId, tokenService.getLoginUserStudy().getUserid()).eq(Recipient::getIsDefault, 1).one();
                .eq(Recipient::getUserId, tokenService.getLoginUserStudy().getUserid())
                .eq(Recipient::getIsDefault, 1).one();
        return AjaxResult.success(goodsService.redeemNow(goodId, recipient));
    }
ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/ITGoodsService.java
@@ -5,10 +5,10 @@
import com.ruoyi.goods.domain.Recipient;
import com.ruoyi.goods.domain.TGoods;
import com.ruoyi.goods.dto.GoodExchangeDTO;
import com.ruoyi.goods.vo.GoodDetailVO;
import com.ruoyi.goods.vo.TGoodsVO;
import java.util.List;
import java.util.Map;
/**
 * <p>
@@ -35,7 +35,7 @@
     * @param recipient 默认收货地址
     * @return 立即兑换页面数据
     */
    Map<String, Object> redeemNow(String goodId, Recipient recipient);
    GoodDetailVO redeemNow(String goodId, Recipient recipient);
    /**
     * 商品兑换
ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/TGoodsServiceImpl.java
@@ -12,6 +12,7 @@
import com.ruoyi.goods.mapper.TGoodsMapper;
import com.ruoyi.goods.service.ITGoodsService;
import com.ruoyi.goods.service.ITOrderService;
import com.ruoyi.goods.vo.GoodDetailVO;
import com.ruoyi.goods.vo.TGoodsVO;
import com.ruoyi.study.api.domain.TUser;
import com.ruoyi.study.api.feignClient.StudyClient;
@@ -22,9 +23,8 @@
import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
 * <p>
@@ -52,18 +52,14 @@
    }
    @Override
    public Map<String, Object> redeemNow(String goodId, Recipient recipient) {
    public GoodDetailVO redeemNow(String goodId, Recipient recipient) {
        // 商品详情
        TGoods goods = lambdaQuery().eq(TGoods::getId, goodId).one();
        Map<String, Object> result = new HashMap<>(8);
        result.put("goodDetail", goods);
        // 用户收货地址
        result.put("address", recipient);
        // 库存预热,redisson分布式锁
        String key = String.format(RedisConstants.GOOD_STOCK, goods.getId());
        RSemaphore semaphore = redissonClient.getSemaphore(key);
        semaphore.trySetPermits(goods.getSurplus());
        return result;
        return new GoodDetailVO(goods,recipient);
    }
    @Override
@@ -81,25 +77,37 @@
        if (user.getIntegral() < needIntegral) {
            throw new GlobalException("兑换失败,当前剩余积分不足!");
        }
        // 检查用户兑换数量是否超过单用户最大兑换数量
        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();
        if (!canExchange) {
            throw new GlobalException("兑换失败,当前兑换数量已超过最大兑换数量,剩余兑换数量为: " + (good.getUserCount() - totalNumber) + "!");
        }
        // redisson分布式锁,防止超卖
        String key = String.format(RedisConstants.GOOD_STOCK, good.getId());
        RSemaphore semaphore = redissonClient.getSemaphore(key);
        boolean tried = semaphore.tryAcquire(number);
        // 兑换失败,库存不足
        if (!tried) {
            semaphore.release(number);
            throw new GlobalException("当前商品库存不足!");
        }
        // 兑换成功,生成订单信息、生成积分明细(积分明细需要远程调用rouyi-study服务)
        TOrder order = orderInfo(goodExchange, recipient, number, goodId, needIntegral);
        if (!orderService.save(order)) {
            throw new GlobalException("订单生成失败!");
        }
        boolean result = orderService.save(order);
        // 远程调用,生成积分明细
        Boolean boo = studyClient.addIntegralDetail(Constants.BURDEN + needIntegral, Constants.SHOPPING_CONSUME).getData();
        if (!boo) {
            throw new GlobalException("生成积分明细失败,请稍后重试!");
        result = result && studyClient.addIntegralDetail(Constants.BURDEN + needIntegral, Constants.SHOPPING_CONSUME).getData();
        // 扣除用户积分
        result = result && studyClient.exchangeIntegral(needIntegral, Constants.BURDEN).getData();
        // 扣除库存
        result = result && this.lambdaUpdate().set(TGoods::getSurplus, good.getSurplus() - number).eq(TGoods::getId, good.getId()).update();
        if (!result) {
            semaphore.release(number);
            throw new GlobalException("商品兑换失败!");
        }
        return true;
        return result;
    }
    private TOrder orderInfo(GoodExchangeDTO goodExchange, Recipient recipient, Integer number, Integer goodId, int needIntegral) {
ruoyi-service/ruoyi-goods/src/main/java/com/ruoyi/goods/vo/GoodDetailVO.java
New file
@@ -0,0 +1,55 @@
package com.ruoyi.goods.vo;
import com.ruoyi.goods.domain.Recipient;
import com.ruoyi.goods.domain.TGoods;
import com.ruoyi.goods.domain.TGoodsType;
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("商品详情返回信息类")
public class GoodDetailVO {
    /**
     * 商品信息
     */
    @ApiModelProperty("商品信息")
    private TGoods good;
    /**
     * 商品分类信息
     */
    @ApiModelProperty("商品分类信息")
    private List<TGoodsType> goodTypes;
    /**
     * 已兑换人数
     */
    @ApiModelProperty("已兑换人数")
    private Integer exchangeNumber;
    /**
     * 用户默认收货地址
     */
    @ApiModelProperty("用户默认收货地址(为:null则调用获取收货地址接口)")
    private Recipient recipient;
    public GoodDetailVO(TGoods good, List<TGoodsType> goodTypes, Integer exchangeNumber) {
        this.good = good;
        this.goodTypes = goodTypes;
        this.exchangeNumber = exchangeNumber;
    }
    public GoodDetailVO(TGoods good, Recipient recipient) {
        this.good = good;
        this.recipient = recipient;
    }
}
ruoyi-service/ruoyi-goods/src/main/resources/mapper/goods/TGoodsMapper.xml
@@ -38,8 +38,8 @@
    <select id="goodRecommend" resultType="com.ruoyi.goods.vo.TGoodsVO">
        select *
        from t_goods g
        where g.price <![CDATA[ <= ]]> (select integral from t_user u where u.id = #{userId})
        ORDER BY g.price desc
        where g.integral <![CDATA[ <= ]]> (select integral from t_user u where u.id = #{userId})
        ORDER BY g.integral desc
        limit 3
    </select>
</mapper>
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TStudyController.java
@@ -4,6 +4,7 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
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;
@@ -17,6 +18,7 @@
import com.ruoyi.study.dto.*;
import com.ruoyi.study.service.*;
import com.ruoyi.study.vo.*;
import com.ruoyi.system.api.model.LoginUserParent;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
@@ -114,8 +116,8 @@
    public R<PageInfo<TSubject>> subjectList(@RequestBody ChoiceSubject query) {
        PageInfo<TSubject> res = new PageInfo<>(query.getPageNumber(), query.getPageSize());
        QueryWrapper<TSubject> wrapper = new QueryWrapper<>();
        if (StringUtils.hasLength(query.getName())){
            wrapper.like("name",query.getName());
        if (StringUtils.hasLength(query.getName())) {
            wrapper.like("name", query.getName());
        }
        if (StringUtils.hasLength(query.getEnglish())) {
            wrapper.like("english", query.getEnglish());
@@ -612,7 +614,7 @@
            @ApiImplicitParam(value = "周目", name = "week", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "所属day", name = "day", dataType = "Integer", required = true)
    })
    public AjaxResult<TUserStudy> studySchedule(@RequestParam Integer week,@RequestParam Integer day) {
    public AjaxResult<TUserStudy> studySchedule(@RequestParam Integer week, @RequestParam Integer day) {
        TUserStudy result = studyService.studySchedule(String.valueOf(tokenService.getLoginUserStudy().getUserid()), week, day);
        return AjaxResult.success(result);
    }
@@ -622,8 +624,8 @@
     */
    @GetMapping("/goodRecommend")
    @ApiOperation(value = "可兑换商品推荐", tags = {"可兑换商品推荐"})
    public R<List<TGoodsVO>> studySchedule() {
        return goodsClient.goodRecommend(String.valueOf(tokenService.getLoginUserStudy().getUserid()));
    public AjaxResult<List<TGoodsVO>> studySchedule() {
        return AjaxResult.success(goodsClient.goodRecommend());
    }
    /**
@@ -648,7 +650,7 @@
            @ApiImplicitParam(value = "周目", name = "week", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "所属day", name = "day", dataType = "Integer", required = true)
    })
    public AjaxResult<Map<String, Object>> listenSelectPicture(@RequestParam Integer week, @RequestParam Integer day) {
    public AjaxResult<StudyListenResultVO> listenSelectPicture(@RequestParam Integer week, @RequestParam Integer day) {
        // 判断当前登录用户是否为 会员
        Boolean isVip = userService.isVip();
        LambdaQueryChainWrapper<TStudyListen> wrapper = studyListenService.lambdaQuery().eq(TStudyListen::getWeek, week)
@@ -673,7 +675,7 @@
            @ApiImplicitParam(value = "周目", name = "week", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "所属day", name = "day", dataType = "Integer", required = true)
    })
    public AjaxResult<Map<String, Object>> pictureSelectVoice(@RequestParam Integer week, @RequestParam Integer day) {
    public AjaxResult<StudyLookResultVO> pictureSelectVoice(@RequestParam Integer week, @RequestParam Integer day) {
        // 判断当前登录用户是否为 会员
        Boolean isVip = userService.isVip();
        LambdaQueryChainWrapper<TStudyLook> wrapper = studyLookService.lambdaQuery().eq(TStudyLook::getWeek, week)
@@ -699,7 +701,7 @@
            @ApiImplicitParam(value = "周目", name = "week", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "所属day", name = "day", dataType = "Integer", required = true)
    })
    public AjaxResult<Map<String, Object>> induceExclude(@RequestParam Integer week, @RequestParam Integer day) {
    public AjaxResult<StudyInductionResultVO> induceExclude(@RequestParam Integer week, @RequestParam Integer day) {
        // 判断当前登录用户是否为 会员
        Boolean isVip = userService.isVip();
        LambdaQueryChainWrapper<TStudyInduction> wrapper = studyInductionService.lambdaQuery().eq(TStudyInduction::getWeek, week)
@@ -724,7 +726,7 @@
            @ApiImplicitParam(value = "周目", name = "week", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "所属day", name = "day", dataType = "Integer", required = true)
    })
    public AjaxResult<Map<String, Object>> questionsAndAnswers(@RequestParam Integer week, @RequestParam Integer day) {
    public AjaxResult<StudyAnswerResultVO> questionsAndAnswers(@RequestParam Integer week, @RequestParam Integer day) {
        // 判断当前登录用户是否为 会员
        Boolean isVip = userService.isVip();
        LambdaQueryChainWrapper<TStudyAnswer> wrapper = studyAnswerService.lambdaQuery().eq(TStudyAnswer::getWeek, week)
@@ -749,10 +751,16 @@
            @ApiImplicitParam(value = "周目", name = "week", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "所属day", name = "day", dataType = "Integer", required = true)
    })
    public AjaxResult<Map<String, Object>> pictureMateVoice(@RequestParam Integer week, @RequestParam Integer day) {
        // 判断当前登录用户是否为 会员 todo
        TStudyPair pair = studyPairService.lambdaQuery().eq(TStudyPair::getWeek, week)
                .eq(TStudyPair::getDay, day).eq(TStudyPair::getDisabled, 0).one();
    public AjaxResult<StudyPairResultVO> pictureMateVoice(@RequestParam Integer week, @RequestParam Integer day) {
        // 判断当前登录用户是否为 会员
        Boolean isVip = userService.isVip();
        LambdaQueryChainWrapper<TStudyPair> wrapper = studyPairService.lambdaQuery().eq(TStudyPair::getWeek, week)
                .eq(TStudyPair::getDay, day).eq(TStudyPair::getDisabled, 0);
        // 非会员只能查看非会员题目,会员可以查看所有题目
        if (!isVip) {
            wrapper.eq(TStudyPair::getIsVip, 0);
        }
        TStudyPair pair = wrapper.one();
        return AjaxResult.success(studyService.pictureMateVoice(week, day, pair));
    }
@@ -768,13 +776,11 @@
            @ApiImplicitParam(value = "难度(0入门、1中级、2困难)", name = "difficulty", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "所属周目", name = "week", dataType = "Integer", required = true)
    })
    public AjaxResult<Map<String, Object>> gameHearing(@RequestParam Integer difficulty, @RequestParam Integer week) {
        Map<String, Object> result = new HashMap<>(8);
    public AjaxResult<StudyGamerResultVO> gameHearing(@RequestParam Integer difficulty, @RequestParam Integer week) {
        TGame game = gameService.lambdaQuery().eq(TGame::getWeek, week)
                .eq(TGame::getDisabled, 0).one();
        game.setIntegral(game.getIntegral().split(",")[difficulty]);
        game.setTime(game.getTime().split(",")[difficulty]);
        result.put("game", game);
        // 检验是否完成难度
        studyService.checkDifficulty(difficulty, week, game);
        List<String> subjectId = getSubjectId(week);
@@ -794,8 +800,8 @@
            // 获取对应的数据并加入结果列表
            subjectData.add(subjectId.get(randomIndex));
        }
        result.put("subject", subjectService.lambdaQuery().in(TSubject::getId, subjectData).eq(TSubject::getState, 1).list());
        return AjaxResult.success(result);
        return AjaxResult.success(new StudyGamerResultVO(game,
                subjectService.lambdaQuery().in(TSubject::getId, subjectData).eq(TSubject::getState, 1).list()));
    }
    /**
@@ -810,10 +816,8 @@
            @ApiImplicitParam(value = "难度(0入门、1中级、2困难)", name = "difficulty", dataType = "Integer", required = true),
            @ApiImplicitParam(value = "所属周目", name = "week", dataType = "Integer", required = true)
    })
    public AjaxResult<Map<String, Object>> gameMemory(@RequestParam Integer difficulty, @RequestParam Integer week) {
        Map<String, Object> result = new HashMap<>(8);
    public AjaxResult<StudyGamerResultVO> gameMemory(@RequestParam Integer difficulty, @RequestParam Integer week) {
        TGame game = gameService.lambdaQuery().eq(TGame::getWeek, week).eq(TGame::getDisabled, 0).one();
        result.put("game", game);
        // 检验是否完成难度
        studyService.checkDifficulty(difficulty, week, game);
        List<String> subjectId = getSubjectId(week);
@@ -833,8 +837,8 @@
            // 获取对应的数据并加入结果列表
            subjectData.add(subjectId.get(randomIndex));
        }
        result.put("subject", subjectService.lambdaQuery().in(TSubject::getId, subjectData).eq(TSubject::getState, 1).list());
        return AjaxResult.success(result);
        return AjaxResult.success(new StudyGamerResultVO(game,
                subjectService.lambdaQuery().in(TSubject::getId, subjectData).eq(TSubject::getState, 1).list()));
    }
    /**
@@ -845,7 +849,7 @@
     */
    @PostMapping("/gameAchievement")
    @ApiOperation(value = "完成游戏-记录游戏测试成绩", tags = {"完成游戏-记录游戏测试成绩"})
    public AjaxResult<?> gameAchievement(@RequestBody CompleteGameDTO completeStudy) {
    public AjaxResult<Boolean> gameAchievement(@RequestBody CompleteGameDTO completeStudy) {
        TGame game = gameService.getById(completeStudy.getGameId());
        // 游戏测试记录
        Boolean add = gameRecordService.add(completeStudy);
@@ -890,15 +894,13 @@
    @ApiImplicitParams({
            @ApiImplicitParam(value = "所属周目", name = "week", dataType = "Integer", required = true)
    })
    public AjaxResult<Map<String, Object>> lookPictureDbu(@RequestParam Integer week) {
    public AjaxResult<StudyStoryListenResultVO> lookPictureDbu(@RequestParam Integer week) {
        // 看图配音信息
        TStoryListen listen = storyListenService.lambdaQuery().eq(TStoryListen::getWeek, week).one();
        // 获取对应图片语音
        List<String> list = Arrays.asList(listen.getLookStory().split(","));
        Map<String, Object> result = new HashMap<>(8);
        result.put("listen", listen);
        result.put("info", subjectService.lambdaQuery().in(TSubject::getId, list).list());
        return AjaxResult.success(result);
        return AjaxResult.success(new StudyStoryListenResultVO(listen,
                subjectService.lambdaQuery().in(TSubject::getId, list).eq(TSubject::getState, 1).list()));
    }
    /**
@@ -911,15 +913,13 @@
    @ApiImplicitParams({
            @ApiImplicitParam(value = "所属周目", name = "week", dataType = "Integer", required = true)
    })
    public AjaxResult<Map<String, Object>> frameworkMemory(@RequestParam Integer week) {
    public AjaxResult<StudyStoryListenResultVO> frameworkMemory(@RequestParam Integer week) {
        // 看图配音信息
        TStoryListen listen = storyListenService.lambdaQuery().eq(TStoryListen::getWeek, week).one();
        // 获取对应图片语音
        List<String> list = Arrays.asList(listen.getStory().split(","));
        Map<String, Object> result = new HashMap<>(8);
        result.put("listen", listen);
        result.put("info", subjectService.lambdaQuery().in(TSubject::getId, list).list());
        return AjaxResult.success(result);
        return AjaxResult.success(new StudyStoryListenResultVO(listen,
                subjectService.lambdaQuery().in(TSubject::getId, list).eq(TSubject::getState, 1).list()));
    }
    /**
@@ -955,7 +955,7 @@
            @ApiImplicitParam(value = "完成答题/完成听故事", name = "method", dataType = "String", required = true)
    })
    public AjaxResult<Boolean> completeStory(@RequestParam Integer integral, @RequestParam Integer storyId,
                              @RequestParam String method) {
                                             @RequestParam String method) {
        // 添加积分明细记录
        Boolean add = integralRecordService.add(String.valueOf(integral), method);
        // 用户信息
@@ -968,16 +968,15 @@
    @GetMapping("/studyRecord")
    @ApiOperation(value = "个人中心-学习记录", tags = {"个人中心-学习记录"})
    public AjaxResult<Map<String, Object>> studyRecord() {
    public AjaxResult<StudyRecordResultVO> studyRecord() {
        Integer userId = tokenService.getLoginUserStudy().getUserid();
        Map<String, Object> result = new HashMap<>(8);
        // 学习记录
        result.put("record", userStudyService.lambdaQuery().eq(TUserStudy::getUserId, userId)
                .eq(TUserStudy::getDisabled, 0).one());
        TUserStudy studyRecord = userStudyService.lambdaQuery().eq(TUserStudy::getUserId, userId)
                .eq(TUserStudy::getDisabled, 0).one();
        // 游戏测试成绩
        result.put("gameAchievement", gameRecordService.lambdaQuery().eq(TGameRecord::getUserId, userId)
                .eq(TGameRecord::getDisabled, 0).list());
        return AjaxResult.success(result);
        List<TGameRecord> gameRecordList = gameRecordService.lambdaQuery().eq(TGameRecord::getUserId, userId)
                .eq(TGameRecord::getDisabled, 0).list();
        return AjaxResult.success(new StudyRecordResultVO(studyRecord,gameRecordList));
    }
    @GetMapping("/integralDetail")
@@ -1006,13 +1005,38 @@
            @ApiImplicitParam(value = "变动源(完成学习、完成游戏...)", name = "method", dataType = "String", required = true)
    })
    public R<Boolean> addIntegralDetail(@RequestParam("integral") String integral, @RequestParam("method") String method) {
        // 当前登录用户
        LoginUserParent userStudy = tokenService.getLoginUserStudy();
        // 生成积分明细信息
        TIntegralRecord integralRecord = new TIntegralRecord();
        integralRecord.setIntegral(integral);
        integralRecord.setMethod(method);
        integralRecord.setUserId(tokenService.getLoginUserStudy().getUserid());
        integralRecord.setUserId(userStudy.getUserid());
        integralRecord.setDisabled(Boolean.FALSE);
        integralRecord.setCreateBy(userStudy.getPhone());
        integralRecord.setCreateTime(new Date());
        integralRecord.setUpdateBy(userStudy.getPhone());
        integralRecord.setUpdateTime(new Date());
        return R.ok(integralRecordService.save(integralRecord));
    }
    /**
     * 用户积分变动(增加或减少)-用于远程调用
     *
     * @param integral 积分变动信息
     * @param method   变动源
     */
    @GetMapping("/exchangeIntegral")
    @ApiOperation(value = "用户积分变动", tags = {"用户积分变动"})
    public R<Boolean> exchangeIntegral(@RequestParam("integral") Integer integral, @RequestParam("method") String method) {
        TUser user = userService.getById(tokenService.getLoginUserStudy().getUserid());
        if (Constants.BURDEN.equals(method)) {
            user.setIntegral(user.getIntegral() - integral);
        } else {
            user.setIntegral(user.getIntegral() + integral);
        }
        return R.ok(userService.updateById(user));
    }
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/controller/TUserController.java
@@ -515,6 +515,17 @@
        return AjaxResult.success();
    }
    /**
     * 获取用户信息
     *
     * @return 用户信息
     */
    @GetMapping("/userInfo")
    @ApiOperation(value = "用户详情", tags = {"用户详情"})
    public R<TUser> userInfo() {
        return R.ok(userService.lambdaQuery().eq(TUser::getId,tokenService.getLoginUserStudy().getUserid()).one());
    }
    @PostMapping("/deleteUser")
    @ApiOperation(value = "注销当前帐号", tags = {"家长端-个人中心"})
    @ApiImplicitParams({
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/ITStudyService.java
@@ -3,9 +3,9 @@
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.study.domain.*;
import com.ruoyi.study.dto.StudyWeekDTO;
import com.ruoyi.study.vo.*;
import java.util.List;
import java.util.Map;
/**
 * <p>
@@ -44,7 +44,7 @@
     * @param studyListens 数据集合
     * @return 单个题组下所包含的所有图片及语音
     */
    Map<String, Object> listenSelectPicture(Integer week, Integer day, List<TStudyListen> studyListens);
    StudyListenResultVO listenSelectPicture(Integer week, Integer day, List<TStudyListen> studyListens);
    /**
     * 自主游戏1-超级听力
@@ -63,7 +63,7 @@
     * @param lookList 数据集合
     * @return 单个题组下所包含的所有图片及语音
     */
    Map<String, Object> pictureSelectVoice(Integer week, Integer day, List<TStudyLook> lookList);
    StudyLookResultVO pictureSelectVoice(Integer week, Integer day, List<TStudyLook> lookList);
    /**
     * 自主学习3-归纳排除
@@ -73,7 +73,7 @@
     * @param inductionList 归纳排除
     * @return 题目信息
     */
    Map<String, Object> induceExclude(Integer week, Integer day, List<TStudyInduction> inductionList);
    StudyInductionResultVO induceExclude(Integer week, Integer day, List<TStudyInduction> inductionList);
    /**
     * 自主学习4-有问有答
@@ -83,7 +83,7 @@
     * @param answerList 有问有答
     * @return 题目信息
     */
    Map<String, Object> questionsAndAnswers(Integer week, Integer day, List<TStudyAnswer> answerList);
    StudyAnswerResultVO questionsAndAnswers(Integer week, Integer day, List<TStudyAnswer> answerList);
    /**
     * 自主学习5-音图相配
@@ -93,6 +93,6 @@
     * @param pair 音图相配
     * @return 题目信息
     */
    Map<String, Object> pictureMateVoice(Integer week, Integer day, TStudyPair pair);
    StudyPairResultVO pictureMateVoice(Integer week, Integer day, TStudyPair pair);
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/service/impl/TStudyServiceImpl.java
@@ -10,6 +10,7 @@
import com.ruoyi.study.service.ITStudyService;
import com.ruoyi.study.service.ITSubjectService;
import com.ruoyi.study.service.ITUserStudyService;
import com.ruoyi.study.vo.*;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@@ -70,64 +71,50 @@
    }
    @Override
    public Map<String, Object> listenSelectPicture(Integer week, Integer day, List<TStudyListen> studyListens) {
    public StudyListenResultVO listenSelectPicture(Integer week, Integer day, List<TStudyListen> studyListens) {
        // 随机获取一组题
        Random rand = new Random();
        TStudyListen data = studyListens.get(rand.nextInt(studyListens.size()));
        List<TSubject> subjectList = getSubjects(data.getSubject().split(","));
        Map<String, Object> result = new HashMap<>(8);
        result.put("data", data);
        result.put("subject", subjectList);
        return result;
        return new StudyListenResultVO(data, subjectList);
    }
    @Override
    public Map<String, Object> pictureSelectVoice(Integer week, Integer day, List<TStudyLook> lookList) {
    public StudyLookResultVO pictureSelectVoice(Integer week, Integer day, List<TStudyLook> lookList) {
        // 随机获取一组题
        Random rand = new Random();
        TStudyLook data = lookList.get(rand.nextInt(lookList.size()));
        List<TSubject> subjectList = getSubjects(data.getSubject().split(","));
        Map<String, Object> result = new HashMap<>(8);
        result.put("data", data);
        result.put("subject", subjectList);
        return result;
        return new StudyLookResultVO(data, subjectList);
    }
    @Override
    public Map<String, Object> induceExclude(Integer week, Integer day, List<TStudyInduction> inductionList) {
    public StudyInductionResultVO induceExclude(Integer week, Integer day, List<TStudyInduction> inductionList) {
        // 随机获取一组题
        Random rand = new Random();
        TStudyInduction data = inductionList.get(rand.nextInt(inductionList.size()));
        List<TSubject> subjectList = getSubjects(data.getSubject().split(","));
        Map<String, Object> result = new HashMap<>(8);
        result.put("data", data);
        result.put("subject", subjectList);
        return result;
        return new StudyInductionResultVO(data, subjectList);
    }
    @Override
    public Map<String, Object> questionsAndAnswers(Integer week, Integer day, List<TStudyAnswer> answerList) {
    public StudyAnswerResultVO questionsAndAnswers(Integer week, Integer day, List<TStudyAnswer> answerList) {
        // 随机获取一组题
        Random rand = new Random();
        TStudyAnswer data = answerList.get(rand.nextInt(answerList.size()));
        // 获取问题题目 和 回答题目
        Map<String, Object> result = new HashMap<>(8);
        List<String> ids = new ArrayList<>();
        ids.add(String.valueOf(data.getSubject()));
        ids.add(String.valueOf(data.getAnswerSubject()));
        result.put("data", data);
        // 有问有答
        result.put("subject", getSubjects(ids.toArray(ids.toArray(new String[0]))));
        return result;
        List<TSubject> subjects = getSubjects(ids.toArray(ids.toArray(new String[0])));
        return new StudyAnswerResultVO(data, subjects);
    }
    @Override
    public Map<String, Object> pictureMateVoice(Integer week, Integer day, TStudyPair pair) {
    public StudyPairResultVO pictureMateVoice(Integer week, Integer day, TStudyPair pair) {
        List<TSubject> subjectList = getSubjects(pair.getSubject().split(","));
        Map<String, Object> result = new HashMap<>(8);
        result.put("data", pair);
        result.put("subject", subjectList);
        return result;
        return new StudyPairResultVO(pair, subjectList);
    }
    /**
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyAnswerResultVO.java
New file
@@ -0,0 +1,33 @@
package com.ruoyi.study.vo;
import com.ruoyi.study.domain.TStudyAnswer;
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;
/**
 * @author HJL
 * @version 1.0
 * @since 2024-05-22 14:48
 */
@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel("有问有答返回信息类")
public class StudyAnswerResultVO extends StudyModelVO {
    /**
     * 自主学习题目信息
     */
    @ApiModelProperty("自主学习题目信息")
    private TStudyAnswer data;
    public StudyAnswerResultVO(TStudyAnswer data, List<TSubject> subjectList) {
        this.data = data;
        super.setSubjectList(subjectList);
    }
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyGamerResultVO.java
New file
@@ -0,0 +1,33 @@
package com.ruoyi.study.vo;
import com.ruoyi.study.domain.TGame;
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;
/**
 * @author HJL
 * @version 1.0
 * @since 2024-05-22 14:48
 */
@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel("超级听力&&超级记忆返回信息类")
public class StudyGamerResultVO extends StudyModelVO {
    /**
     * 趣味游戏题目信息
     */
    @ApiModelProperty("趣味游戏题目信息")
    private TGame data;
    public StudyGamerResultVO(TGame data, List<TSubject> subjectList) {
        this.data = data;
        super.setSubjectList(subjectList);
    }
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyInductionResultVO.java
New file
@@ -0,0 +1,33 @@
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;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
/**
 * @author HJL
 * @version 1.0
 * @since 2024-05-22 14:48
 */
@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel("归纳排除返回信息类")
public class StudyInductionResultVO extends StudyModelVO {
    /**
     * 自主学习题目信息
     */
    @ApiModelProperty("自主学习题目信息")
    private TStudyInduction data;
    public StudyInductionResultVO(TStudyInduction data, List<TSubject> subjectList) {
        this.data = data;
        super.setSubjectList(subjectList);
    }
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyListenResultVO.java
New file
@@ -0,0 +1,32 @@
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;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
/**
 * @author HJL
 * @version 1.0
 * @since 2024-05-22 14:39
 */
@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel("听音选图返回信息类")
public class StudyListenResultVO extends StudyModelVO {
    /**
     * 自主学习题目信息
     */
    @ApiModelProperty("自主学习题目信息")
    private TStudyListen data;
    public StudyListenResultVO(TStudyListen data, List<TSubject> subjectList) {
        this.data = data;
        super.setSubjectList(subjectList);
    }
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyLookResultVO.java
New file
@@ -0,0 +1,33 @@
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;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
/**
 * @author HJL
 * @version 1.0
 * @since 2024-05-22 14:48
 */
@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel("看图选音返回信息类")
public class StudyLookResultVO extends StudyModelVO{
    /**
     * 自主学习题目信息
     */
    @ApiModelProperty("自主学习题目信息")
    private TStudyLook data;
    public StudyLookResultVO(TStudyLook data, List<TSubject> subjectList) {
        this.data = data;
        super.setSubjectList(subjectList);
    }
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyModelVO.java
New file
@@ -0,0 +1,23 @@
package com.ruoyi.study.vo;
import com.ruoyi.study.domain.TSubject;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
 * @author HJL
 * @version 1.0
 * @since 2024-05-22 14:47
 */
@Data
public class StudyModelVO {
    /**
     * 自主学习题目所包含录音图片等
     */
    @ApiModelProperty("自主学习题目所包含录音图片等")
    private List<TSubject> subjectList;
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyPairResultVO.java
New file
@@ -0,0 +1,33 @@
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;
/**
 * @author HJL
 * @version 1.0
 * @since 2024-05-22 14:48
 */
@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel("音图相配返回信息类")
public class StudyPairResultVO extends StudyModelVO {
    /**
     * 自主学习题目信息
     */
    @ApiModelProperty("自主学习题目信息")
    private TStudyPair data;
    public StudyPairResultVO(TStudyPair data, List<TSubject> subjectList) {
        this.data = data;
        super.setSubjectList(subjectList);
    }
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyRecordResultVO.java
New file
@@ -0,0 +1,36 @@
package com.ruoyi.study.vo;
import com.ruoyi.study.domain.TGameRecord;
import com.ruoyi.study.domain.TUserStudy;
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:39
 */
@Data
@ApiModel("个人中心-学习记录返回信息类")
public class StudyRecordResultVO{
    /**
     * 学习记录
     */
    @ApiModelProperty("学习记录")
    private TUserStudy record;
    /**
     * 游戏测试成绩
     */
    @ApiModelProperty("游戏测试成绩")
    private List<TGameRecord> gameRecordList;
    public StudyRecordResultVO(TUserStudy record, List<TGameRecord> gameRecordList) {
        this.record = record;
        this.gameRecordList = gameRecordList;
    }
}
ruoyi-service/ruoyi-study/src/main/java/com/ruoyi/study/vo/StudyStoryListenResultVO.java
New file
@@ -0,0 +1,32 @@
package com.ruoyi.study.vo;
import com.ruoyi.study.domain.TStoryListen;
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;
/**
 * @author HJL
 * @version 1.0
 * @since 2024-05-22 14:39
 */
@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel("自主故事-看图配音&&框架记忆返回信息类")
public class StudyStoryListenResultVO extends StudyModelVO {
    /**
     * 自主故事-看图配音&&框架记忆题目信息
     */
    @ApiModelProperty("自主故事-看图配音&&框架记忆题目信息")
    private TStoryListen data;
    public StudyStoryListenResultVO(TStoryListen data, List<TSubject> subjectList) {
        this.data = data;
        super.setSubjectList(subjectList);
    }
}